Skip to content

Commit f040371

Browse files
committed
Finished Embedding Documents demo, plus minor fixes
1 parent 43c7327 commit f040371

5 files changed

Lines changed: 29 additions & 685 deletions

File tree

244 KB
Loading

documentation/modules/ROOT/pages/embed_documents.adoc

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@ quarkus extension add websockets smallrye-context-propagation langchain4j-core
3636
--
3737
====
3838

39+
This section exceptionally needs an external LangChain4j extension, which we'll manually add to our POM file here:
40+
41+
[.console-input]
42+
[source,xml]
43+
----
44+
<dependency>
45+
<groupId>dev.langchain4j</groupId>
46+
<artifactId>langchain4j</artifactId>
47+
<version>0.24.0</version>
48+
</dependency>
49+
----
50+
3951
== Adding temperature property to your configuration
4052

4153
The "temperature" parameter in AI language models controls the randomness of text generation. Lower values result in more predictable outputs, while higher values encourage creativity and diversity in responses.
@@ -425,7 +437,7 @@ public class ChatSocket {
425437

426438
Finally, let's add our chat frontend.
427439

428-
Create a new `index.html` Java record in `src/main/resources/META-INF/resources` with the following contents:
440+
Create a new `chat-assistant.html` file in `src/main/resources/META-INF/resources` with the following contents:
429441

430442
[.console-input]
431443
[source,html]
@@ -541,15 +553,11 @@ Create a new `index.html` Java record in `src/main/resources/META-INF/resources`
541553

542554
== Invoke the endpoint
543555

544-
You can check your prompt implementation by pointing your browser to http://localhost:8080/chat[window=_blank]
556+
You can check your prompt implementation by pointing your browser to http://localhost:8080/chat-assistant.html[window=_blank]
545557

546558

547559
An example of output (it can vary on each prompt execution):
548560

549-
[.console-output]
550-
[source,text]
551-
----
552-
553-
----
561+
image::chat-assistant.png[]
554562

555563

Lines changed: 0 additions & 338 deletions
Original file line numberDiff line numberDiff line change
@@ -1,340 +1,2 @@
11
= Bringing Kubernetes and Kafka to the party
22

3-
Quarkus provides a novel reactive API called Mutiny, with the goal of easing the development of highly scalable, resilient, and asynchronous systems.
4-
5-
In this chapter we're going to see some examples of how Mutiny changes the design of our Quarkus applications.
6-
to online beer database (https://punkapi.com/documentation/v2) to retrieve beer information.
7-
This API does not return all beers at once, so we'll need to navigate through the pages to fetch all the information.
8-
Then we're going to filter all the beers with an ABV greater than 15.0 and return all these beers in a Reactive REST endpoint.
9-
10-
== Add the Mutiny extension
11-
12-
Create a new Quarkus project, for example using https://code.quarkus.io/ website.
13-
14-
Then open a new terminal window, and make sure you’re at the root of your `{project-name}` project, then run:
15-
16-
[tabs]
17-
====
18-
Maven::
19-
+
20-
--
21-
[.console-input]
22-
[source,bash,subs="+macros,+attributes"]
23-
----
24-
./mvnw quarkus:add-extension -Dextension=quarkus-mutiny,quarkus-rest-client-reactive-jsonb,quarkus-resteasy-reactive-jsonb
25-
----
26-
27-
--
28-
Quarkus CLI::
29-
+
30-
--
31-
[.console-input]
32-
[source,bash,subs="+macros,+attributes"]
33-
----
34-
quarkus extension add quarkus-mutiny,quarkus-rest-client-reactive-jsonb,quarkus-resteasy-reactive-jsonb
35-
----
36-
--
37-
====
38-
39-
== Create Beer POJO
40-
41-
Create a new `Beer` Java class in `src/main/java` in the `org.acme` package with the following contents:
42-
43-
[.console-input]
44-
[source,java]
45-
----
46-
package org.acme;
47-
48-
import jakarta.json.bind.annotation.JsonbCreator;
49-
50-
public class Beer {
51-
52-
private String name;
53-
private String tagline;
54-
private double abv;
55-
56-
private Beer(String name, String tagline, double abv) {
57-
this.name = name;
58-
this.tagline = tagline;
59-
this.abv = abv;
60-
}
61-
62-
@JsonbCreator
63-
public static Beer of(String name, String tagline, double abv) {
64-
return new Beer(name, tagline, abv);
65-
}
66-
67-
public String getName() {
68-
return name;
69-
}
70-
71-
public String getTagline() {
72-
return tagline;
73-
}
74-
75-
public double getAbv() {
76-
return abv;
77-
}
78-
79-
}
80-
----
81-
82-
== Create BeerService
83-
84-
Now we're going to implement a Java interface that mimics the remote REST endpoint.
85-
86-
Create a new `BeerService` Java interface in `src/main/java` in the `org.acme` package with the following contents:
87-
88-
[.console-input]
89-
[source,java]
90-
----
91-
package org.acme;
92-
93-
import java.util.List;
94-
95-
import jakarta.json.JsonArray;
96-
import jakarta.ws.rs.GET;
97-
import jakarta.ws.rs.Path;
98-
import jakarta.ws.rs.PathParam;
99-
import jakarta.ws.rs.Produces;
100-
import jakarta.ws.rs.QueryParam;
101-
import jakarta.ws.rs.core.MediaType;
102-
103-
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
104-
105-
import io.smallrye.mutiny.Uni;
106-
107-
@Path("/v2")
108-
@RegisterRestClient
109-
public interface BeerService {
110-
111-
@GET
112-
@Path("/beers")
113-
@Produces(MediaType.APPLICATION_JSON)
114-
Uni<List<Beer>> getBeers(@QueryParam("page") int page);
115-
}
116-
----
117-
118-
== Configure REST Client properties
119-
120-
Add the following properties to your `application.properties` in `src/main/resources`:
121-
122-
[.console-input]
123-
[source,properties]
124-
----
125-
org.acme.BeerService/mp-rest/url=https://api.punkapi.com
126-
----
127-
128-
== Pagination + Filtering
129-
130-
We want to query all the beers page by page and filter by its _abv_ value.
131-
132-
image::pagination.png[]
133-
134-
=== Create BeerResource
135-
136-
Create a new `BeerResource` Java class in `src/main/java` in the `org.acme` package with the following contents:
137-
138-
[.console-input]
139-
[source,java]
140-
----
141-
package org.acme;
142-
143-
import java.util.List;
144-
import java.util.concurrent.atomic.AtomicInteger;
145-
146-
import jakarta.json.Json;
147-
import jakarta.json.JsonArray;
148-
import jakarta.json.JsonMergePatch;
149-
import jakarta.json.JsonObject;
150-
import jakarta.json.JsonValue;
151-
import jakarta.ws.rs.GET;
152-
import jakarta.ws.rs.Path;
153-
import jakarta.ws.rs.PathParam;
154-
155-
import org.eclipse.microprofile.rest.client.inject.RestClient;
156-
import io.smallrye.mutiny.Multi;
157-
import io.smallrye.mutiny.Uni;
158-
159-
@Path("/beer")
160-
public class BeerResource {
161-
162-
@RestClient
163-
BeerService beerService;
164-
165-
@GET
166-
public Multi<Beer> beers() {
167-
return Multi.createBy().repeating() // <1>
168-
.uni(
169-
() -> new AtomicInteger(1),
170-
i -> beerService.getBeers(i.getAndIncrement()) // <2>
171-
)
172-
.until(List::isEmpty) // <3>
173-
.onItem().<Beer>disjoint() // <4>
174-
.select().where(b -> b.getAbv() > 15.0); // <5>
175-
}
176-
}
177-
----
178-
<1> Creates a `Multi`.
179-
<2> The supplier will start with `1` and will query the remote endpoint asking for page `i`.
180-
<3> The multi will end when the beer list returned is empty.
181-
<4> We dismember all the returned lists and create a sequence of beers.
182-
<5> And then we filter the `Multi` with beers with `ABV > 15.0`.
183-
184-
=== Invoke the endpoint
185-
186-
You can check your new implementation by pointing your browser to http://localhost:8080/beer[window=_blank]
187-
188-
You can also run the following command:
189-
190-
[.console-input]
191-
[source,bash]
192-
----
193-
curl localhost:8080/beer
194-
----
195-
196-
[.console-output]
197-
[source,json]
198-
----
199-
[
200-
{
201-
"abv": 55,
202-
"name": "The End Of History",
203-
"tagline": "The World's Strongest Beer."
204-
},
205-
{
206-
"abv": 16.5,
207-
"name": "Anarchist Alchemist",
208-
"tagline": "Triple Hopped Triple Ipa."
209-
},
210-
{
211-
"abv": 15.2,
212-
"name": "Lumberjack Stout",
213-
"tagline": "Blueberry Bacon Stout."
214-
},
215-
{
216-
"abv": 18.3,
217-
"name": "Bowman's Beard - B-Sides",
218-
"tagline": "English Barley Wine."
219-
},
220-
{
221-
"abv": 41,
222-
"name": "Sink The Bismarck!",
223-
"tagline": "IPA For The Dedicated."
224-
},
225-
{
226-
"abv": 16.2,
227-
"name": "Tokyo*",
228-
"tagline": "Intergalactic Stout. Rich. Smoky. Fruity."
229-
},
230-
{
231-
"abv": 18,
232-
"name": "AB:02",
233-
"tagline": "Triple Dry Hopped Imperial Red Ale."
234-
},
235-
{
236-
"abv": 17.2,
237-
"name": "Black Tokyo Horizon (w/Nøgne Ø & Mikkeller)",
238-
"tagline": "Imperial Stout Collaboration."
239-
},
240-
{
241-
"abv": 16.1,
242-
"name": "Dog D",
243-
"tagline": "Anniversary Imperial Stout."
244-
},
245-
{
246-
"abv": 32,
247-
"name": "Tactical Nuclear Penguin",
248-
"tagline": "Uber Imperial Stout."
249-
},
250-
{
251-
"abv": 16.1,
252-
"name": "Dog E",
253-
"tagline": "Ninth Anniversary Imperial Stout."
254-
},
255-
{
256-
"abv": 17,
257-
"name": "Dog G",
258-
"tagline": "11th Anniversary Imperial Stout."
259-
}
260-
]
261-
----
262-
263-
== Parallel Calls
264-
265-
Suppose that now, you want to query two beers by its id, (so execute two requests against the remote API), and then compare its _abv_ values.
266-
267-
image::parallel.png[]
268-
269-
=== Modify BeerService
270-
271-
Open `BeerService` interface and add the following method to get a beer:
272-
273-
[.console-input]
274-
[source,java]
275-
----
276-
@GET
277-
@Path("/beers/{id}")
278-
@Produces(MediaType.APPLICATION_JSON)
279-
Uni<JsonArray> getBeer(@PathParam("id") int id);
280-
----
281-
282-
=== Modify BeerResource
283-
284-
Open `BeerResource` class and add the following methods to do in parallel the both calls.
285-
286-
[.console-input]
287-
[source,java]
288-
----
289-
@GET
290-
@Path("/{beerA}/{beerB}")
291-
public Uni<JsonValue> compare(@PathParam("beerA") int beerA, @PathParam("beerB") int beerB) {
292-
Uni<JsonArray> beer1 = beerService.getBeer(beerA); // <1>
293-
Uni<JsonArray> beer2 = beerService.getBeer(beerB); // <2>
294-
295-
return Uni.combine()
296-
.all()
297-
.unis(beer1, beer2) // <3>
298-
.with((b1, b2) -> this.compare(b1, b2)); // <4>
299-
}
300-
301-
private JsonValue compare(JsonArray beerA, JsonArray beerB) {
302-
JsonObject source = beerA.get(0).asJsonObject();
303-
JsonObject target = beerB.get(0).asJsonObject();
304-
305-
String beerAName = source.getString("name");
306-
String beerBName = target.getString("name");
307-
308-
double beerAAbv = source.getJsonNumber("abv").doubleValue();
309-
double beerBAbv = target.getJsonNumber("abv").doubleValue();
310-
311-
return Json.createObjectBuilder()
312-
.add("source-name", beerAName)
313-
.add("target-name", beerBName)
314-
.add("source-abv", beerAAbv)
315-
.add("target-abv", beerBAbv)
316-
.build();
317-
}
318-
----
319-
<1> Executes request for first beer
320-
<2> Executes request for second beer
321-
<3> Waits until both requests returns a response
322-
<4> Compare both beers and returns an object with the result
323-
324-
=== Invoke the endpoint
325-
326-
You can check your new implementation by pointing your browser to http://localhost:8080/beer/1/2[window=_blank]
327-
328-
You can also run the following command:
329-
330-
[.console-input]
331-
[source,bash]
332-
----
333-
curl localhost:8080/beer/1/2
334-
----
335-
336-
[.console-output]
337-
[source,json]
338-
----
339-
{"source-name":"Buzz","target-name":"Trashy Blonde","source-abv":4.5,"target-abv":4.1}
340-
----

0 commit comments

Comments
 (0)