Nyob zoo sawv daws! Ntawm no nws yog - peb qhov kawg tshaj tawm hauv Quarkus series! (Los ntawm txoj kev, saib peb lub vev xaib
Π
Txij li version 0.17.0,
Nws yog xav tias koj twb tau siv AMQ Online ntawm OpenShift platform (yog tias tsis yog, saib
Txhawm rau pib, peb yuav tsim ib daim ntawv thov Quarkus uas yuav yog qhov kev txiav txim yooj yim uas siv cov lus xa rov qab. Daim ntawv thov no yuav suav nrog lub tshuab hluav taws xob txiav txim uas xa cov lus xaj mus rau cov kab lus ntawm lub sijhawm tas mus li, nrog rau cov txheej txheem kev txiav txim uas yuav ua cov lus los ntawm kab thiab tsim cov ntawv pom zoo hauv qhov browser.
Thaum peb tau tsim daim ntawv thov, peb yuav qhia koj yuav ua li cas rau embed qhov kev xa xov teeb tsa rau hauv daim ntawv thov thiab siv AMQ Online los muab cov peev txheej peb xav tau ntawm lub kaw lus.
Quarkus app
Peb daim ntawv thov Quarkus khiav ntawm OpenShift thiab yog qhov hloov kho ntawm qhov program
Order generator
Lub tshuab hluav taws xob tsuas yog xa cov ntawv xaj ID loj hlob mus rau "kev txiav txim" chaw nyob txhua 5 vib nas this.
@ApplicationScoped
public class OrderGenerator {
private int orderId = 1;
@Outgoing("orders")
public Flowable<Integer> generate() {
return Flowable.interval(5, TimeUnit.SECONDS)
.map(tick -> orderId++);
}
}
Order Processor
Tus neeg tswj kev txiav txim yog qhov yooj yim dua, nws tsuas yog xa rov qab daim ID nkag mus rau qhov chaw nyob "confirmations".
@ApplicationScoped
public class OrderProcessor {
@Incoming("orders")
@Outgoing("confirmations")
public Integer process(Integer order) {
// ΠΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΡ ΡΠ°Π²Π΅Π½ ΡΠ΄Π²ΠΎΠ΅Π½Π½ΠΎΠΌΡ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΡ Π·Π°ΠΊΠ°Π·Π° <img draggable="false" class="emoji" alt=":-)" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f642.svg">
return order * 2;
}
}
Cov ntaub ntawv pov thawj
Cov ntaub ntawv lees paub yog HTTP kawg rau sau cov ntawv lees paub tsim los ntawm peb daim ntawv thov.
@Path("/confirmations")
public class ConfirmationResource {
@Inject
@Stream("confirmations") Publisher<Integer> orders;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "hello";
}
@GET
@Path("/stream")
@Produces(MediaType.SERVER_SENT_EVENTS)
public Publisher<Integer> stream() {
return orders;
}
}
hloov
Txhawm rau txuas rau AMQ Online, peb daim ntawv thov yuav xav tau qee cov ntaub ntawv teeb tsa, xws li: Quarkus connector configuration, AMQP endpoint information thiab client credentials. Nws yog, ntawm chav kawm, zoo dua khaws tag nrho cov ntaub ntawv teeb tsa hauv ib qho chaw, tab sis peb yuav txhob txwm cais lawv los qhia cov kev xaiv tau rau kev teeb tsa Quarkus daim ntawv thov.
Cov khoom sib txuas
Connector configuration tuaj yeem muab tau ntawm lub sijhawm sib sau siv cov ntaub ntawv thov cov khoom:
mp.messaging.outgoing.orders.connector=smallrye-amqp
mp.messaging.incoming.orders.connector=smallrye-amqp
Txhawm rau khaws tej yam yooj yim, peb tsuas yog siv cov kab lus rau qhov chaw nyob "orders". Thiab qhov "confirmations" chaw nyob hauv peb daim ntawv thov yuav siv cov kab hauv nco.
AMQP qhov kawg
Thaum sib sau ua ke, lub npe hostname thiab tus lej chaw nres nkoj rau AMQP qhov kawg tsis paub, yog li lawv yuav tsum tau txhaj tshuaj. Qhov kawg tuaj yeem teeb tsa hauv configmap uas yog tsim los ntawm AMQ Online, yog li peb yuav txhais lawv los ntawm ib puag ncig hloov pauv hauv daim ntawv thov manifest:
spec:
template:
spec:
containers:
- env:
- name: AMQP_HOST
valueFrom:
configMapKeyRef:
name: quarkus-config
key: service.host
- name: AMQP_PORT
valueFrom:
configMapKeyRef:
name: quarkus-config
key: service.port.amqp
Cov ntaub ntawv pov thawj
Cov kev pabcuam tus lej token tuaj yeem siv los txheeb xyuas peb daim ntawv thov rau OpenShift. Txhawm rau ua qhov no, koj yuav tsum xub tsim ib qho kev cai ConfigSource uas yuav nyeem cov ntawv pov thawj token los ntawm cov ntaub ntawv pov thawj:
public class MessagingCredentialsConfigSource implements ConfigSource {
private static final Set<String> propertyNames;
static {
propertyNames = new HashSet<>();
propertyNames.add("amqp-username");
propertyNames.add("amqp-password");
}
@Override
public Set<String> getPropertyNames() {
return propertyNames;
}
@Override
public Map<String, String> getProperties() {
try {
Map<String, String> properties = new HashMap<>();
properties.put("amqp-username", "@@serviceaccount@@");
properties.put("amqp-password", readTokenFromFile());
return properties;
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Override
public String getValue(String key) {
if ("amqp-username".equals(key)) {
return "@@serviceaccount@@";
}
if ("amqp-password".equals(key)) {
try {
return readTokenFromFile();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
return null;
}
@Override
public String getName() {
return "messaging-credentials-config";
}
private static String readTokenFromFile() throws IOException {
return new String(Files.readAllBytes(Paths.get("/var/run/secrets/kubernetes.io/serviceaccount/token")), StandardCharsets.UTF_8);
}
}
Tsim thiab xa daim ntawv thov
Txij li thaum daim ntawv thov yuav tsum tau muab tso ua ke rau hauv cov ntaub ntawv executable, yuav tsum muaj GraalVM virtual tshuab. Yog xav paub ntxiv txog kev teeb tsa ib puag ncig rau qhov no, saib cov lus qhia sib xws hauv
Tom qab ntawd, ua raws li cov lus qhia tau muab rau ntawd, koj yuav tsum rub tawm qhov chaw, tsim thiab xa peb daim ntawv thov:
git clone https://github.com/EnMasseProject/enmasse-example-clients
cd enmasse-example-clients/quarkus-example-client
oc new-project myapp
mvn -Pnative -Dfabric8.mode=openshift -Dfabric8.build.strategy=docker package fabric8:build fabric8:resource fabric8:apply
Tom qab cov lus txib no, daim ntawv thov yuav raug xa mus, tab sis yuav tsis pib kom txog thaum peb teeb tsa cov kev xa xov peb xav tau hauv AMQ Online.
Kev teeb tsa lub tshuab xa xov
Tam sim no txhua yam uas tseem tshuav yog los teeb tsa cov peev txheej uas peb daim ntawv thov xav tau hauv kev xa xov. Txhawm rau ua qhov no, koj yuav tsum tsim: 1) qhov chaw nyob kom pib qhov kev xa xov kawg; 2) chaw nyob los teeb tsa qhov chaw nyob peb siv hauv daim ntawv thov; 3) Cov neeg siv xa xov los teeb tsa cov neeg siv khoom pov thawj.
Chaw nyob
Qhov Chaw Nyob Chaw Nyob hauv AMQ Online yog ib pab pawg ntawm cov chaw nyob uas qhia txog qhov kawg ntawm kev sib txuas thiab kev lees paub thiab kev tso cai txoj cai. Thaum koj tsim qhov chaw nyob, koj tuaj yeem qhia meej tias cov ntsiab lus xa xov yuav raug nthuav tawm li cas:
apiVersion: enmasse.io/v1beta1
kind: AddressSpace
metadata:
name: quarkus-example
spec:
type: brokered
plan: brokered-single-broker
endpoints:
- name: messaging
service: messaging
exports:
- name: quarkus-config
kind: configmap
Chaw nyob
Chaw nyob yog siv los xa thiab txais cov lus. Txhua qhov chaw nyob muaj ib hom, uas txiav txim siab nws cov semantics, nrog rau cov phiaj xwm, uas qhia txog cov peev txheej uas yuav tsum tau khaws tseg. Qhov chaw nyob tuaj yeem txiav txim siab, piv txwv li, zoo li no:
apiVersion: enmasse.io/v1beta1
kind: Address
metadata:
name: quarkus-example.orders
spec:
address: orders
type: queue
plan: brokered-queue
Messaging neeg siv
Txhawm rau kom ntseeg tau tias tsuas yog cov ntawv thov kev ntseeg siab tuaj yeem xa thiab txais cov lus rau koj qhov chaw nyob, koj yuav tsum tsim tus neeg siv hauv kev xa xov. Rau cov ntawv thov ua haujlwm ntawm pawg, cov neeg siv khoom tuaj yeem lees paub siv tus account OpenShift kev pabcuam. Tus neeg siv "serviceaccount" tuaj yeem txhais tau, piv txwv li, zoo li no:
apiVersion: user.enmasse.io/v1beta1
kind: MessagingUser
metadata:
name: quarkus-example.app
spec:
username: system:serviceaccount:myapp:default
authentication:
type: serviceaccount
authorization:
- operations: ["send", "recv"]
addresses: ["orders"]
Tso cai rau configure daim ntawv thov
Yuav kom AMQ Online los tsim cov configmap uas peb tau siv los embed AMQP cov ntaub ntawv kawg, Lub Luag Haujlwm thiab RoleBinding yuav tsum tau teeb tsa:
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: quarkus-config
spec:
rules:
- apiGroups: [ "" ]
resources: [ "configmaps" ]
verbs: [ "create" ]
- apiGroups: [ "" ]
resources: [ "configmaps" ]
resourceNames: [ "quarkus-config" ]
verbs: [ "get", "update", "patch" ]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: quarkus-config
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: quarkus-config
subjects:
- kind: ServiceAccount
name: address-space-controller
namespace: amq-online-infra
Yuav ua li cas siv configurations
Koj tuaj yeem siv qhov kev teeb tsa kev xa xov zoo li no:
cd enmasse-example-clients/quarkus-example-client
oc project myapp
oc apply -f src/main/resources/k8s/addressspace
oc apply -f src/main/resources/k8s/address
Kev txheeb xyuas daim ntawv thov
Txhawm rau kom paub tseeb tias daim ntawv thov tau pib, ua ntej ntawm tag nrho, cia peb tshawb xyuas seb cov chaw nyob sib raug tau tsim thiab ua haujlwm:
until [[ `oc get address quarkus-example.prices -o jsonpath='{.status.phase}'` == "Active" ]]; do echo "Not yet ready"; sleep 5; done
Tom qab ntawd cia peb tshawb xyuas daim ntawv thov txoj kev URL (tsuas yog qhib qhov chaw nyob hauv qhov browser):
echo "http://$(oc get route quarkus-example-client -o jsonpath='{.spec.host}')/prices.html"
Tus browser yuav tsum qhia tias daim pib tau hloov kho ib ntus raws li cov lus xa thiab tau txais los ntawm AMQ Online.
Summing txog
Yog li peb tau sau ib daim ntawv thov Quarkus uas siv AMQP rau kev xa xov, teeb tsa daim ntawv thov kom khiav ntawm Red Hat OpenShift platform, thiab siv nws txoj kev teeb tsa raws li AMQ Online teeb tsa. Peb mam li tsim cov manifests xav tau los pib qhov kev xa xov rau peb daim ntawv thov.
Qhov no xaus cov koob txog Quarkus, tab sis muaj ntau yam tshiab thiab nthuav ua ntej, nyob twj ywm!
Tau qhov twg los: www.hab.com