ΠΡΠ΅ΠΌ ΠΏΡΠΈΠ²Π΅Ρ! ΠΠΎΡ ΠΈ ΠΎΠ½ β Π½Π°Ρ Π·Π°ΠΊΠ»ΡΡΠΈΡΠ΅Π»ΡΠ½ΡΠΉ ΠΏΠΎΡΡ ΠΈΠ· ΡΠ΅ΡΠΈΠΈ ΠΏΡΠΎ Quarkus! (ΠΡΡΠ°ΡΠΈ, ΡΠΌΠΎΡΡΠΈΡΠ΅ Π½Π°Ρ Π²Π΅Π±ΠΈΠ½Π°Ρ
Π
ΠΠ°ΡΠΈΠ½Π°Ρ Ρ Π²Π΅ΡΡΠΈΠΈ 0.17.0,
ΠΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΡΡΡ, ΡΡΠΎ Π²Ρ ΡΠΆΠ΅ ΡΠ°Π·Π²Π΅ΡΠ½ΡΠ»ΠΈ AMQ Online Π½Π° ΠΏΠ»Π°ΡΡΠΎΡΠΌΠ΅ OpenShift (Π΅ΡΠ»ΠΈ Π½Π΅Ρ, ΡΠΎ ΡΠΌ.
ΠΠ»Ρ Π½Π°ΡΠ°Π»Π° ΠΌΡ ΡΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Quarkus, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π±ΡΠ΄Π΅Ρ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΡΡ ΡΠΎΠ±ΠΎΠΉ ΠΏΡΠΎΡΡΡΡ ΡΠΈΡΡΠ΅ΠΌΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ Π·Π°ΠΊΠ°Π·ΠΎΠ² Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΡΠ΅Π°ΠΊΡΠΈΠ²Π½ΠΎΠ³ΠΎ ΠΎΠ±ΠΌΠ΅Π½Π° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΠΌΠΈ. ΠΡΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π±ΡΠ΄Π΅Ρ Π²ΠΊΠ»ΡΡΠ°ΡΡ Π² ΡΠ΅Π±Ρ Π³Π΅Π½Π΅ΡΠ°ΡΠΎΡ Π·Π°ΠΊΠ°Π·ΠΎΠ², ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡΠΈΠΉ Π·Π°ΠΊΠ°Π·Ρ Π² ΠΎΡΠ΅ΡΠ΅Π΄Ρ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ Ρ ΡΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½Π½ΡΠΌ ΠΈΠ½ΡΠ΅ΡΠ²Π°Π»ΠΎΠΌ, Π° ΡΠ°ΠΊΠΆΠ΅ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ Π·Π°ΠΊΠ°Π·ΠΎΠ², ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΈΠ· ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ ΠΈ ΡΠΎΡΠΌΠΈΡΠΎΠ²Π°ΡΡ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΡ, Π΄ΠΎΡΡΡΠΏΠ½ΡΠ΅ Π΄Π»Ρ ΠΏΡΠΎΡΠΌΠΎΡΡΠ° Π² Π±ΡΠ°ΡΠ·Π΅ΡΠ΅.
ΠΠΎΡΠ»Π΅ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΌΡ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ, ΠΊΠ°ΠΊ Π²Π½Π΅Π΄ΡΡΡΡ Π² Π½Π΅Π³ΠΎ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ ΡΠΈΡΡΠ΅ΠΌΡ ΠΎΠ±ΠΌΠ΅Π½Π° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΠΌΠΈ ΠΈ Π·Π°Π΄Π΅ΠΉΡΡΠ²ΡΠ΅ΠΌ AMQ Online, ΡΡΠΎΠ±Ρ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ Π½Π° ΡΡΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΠ΅ Π½ΡΠΆΠ½ΡΠ΅ Π½Π°ΠΌ ΡΠ΅ΡΡΡΡΡ.
ΠΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Quarkus
ΠΠ°ΡΠ΅ Quarkus-ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ Π½Π° OpenShift ΠΈ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ ΡΠΎΠ±ΠΎΠΉ ΠΌΠΎΠ΄ΠΈΡΠΈΡΠΈΡΠΎΠ²Π°Π½Π½ΡΡ Π²Π΅ΡΡΠΈΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ
ΠΠ΅Π½Π΅ΡΠ°ΡΠΎΡ Π·Π°ΠΊΠ°Π·ΠΎΠ²
ΠΠ΅Π½Π΅ΡΠ°ΡΠΎΡ ΠΊΠ°ΠΆΠ΄ΡΠ΅ 5 ΡΠ΅ΠΊΡΠ½Π΄ ΠΏΡΠΎΡΡΠΎ ΠΌΠΎΠ½ΠΎΡΠΎΠ½Π½ΠΎ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅Ρ ΡΠ°ΡΡΡΡΠΈΠ΅ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΡ Π·Π°ΠΊΠ°Π·ΠΎΠ² Π½Π° Π°Π΄ΡΠ΅Ρ Β«ordersΒ».
@ApplicationScoped
public class OrderGenerator {
private int orderId = 1;
@Outgoing("orders")
public Flowable<Integer> generate() {
return Flowable.interval(5, TimeUnit.SECONDS)
.map(tick -> orderId++);
}
}
ΠΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ Π·Π°ΠΊΠ°Π·ΠΎΠ²
ΠΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ Π·Π°ΠΊΠ°Π·ΠΎΠ² Π΅ΡΠ΅ ΠΏΡΠΎΡΠ΅, ΠΎΠ½ Π²ΡΠ΅Π³ΠΎ Π»ΠΈΡΡ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΡ Π½Π° Π°Π΄ΡΠ΅Ρ Β«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;
}
}
Π Π΅ΡΡΡΡΡ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΡ
Π Π΅ΡΡΡΡ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΡ β ΡΡΠΎ ΠΊΠΎΠ½Π΅ΡΠ½Π°Ρ ΡΠΎΡΠΊΠ° HTTP Π΄Π»Ρ Π»ΠΈΡΡΠΈΠ½Π³Π° ΡΡΠΎΡΠΌΠΈΡΠΎΠ²Π°Π½Π½ΡΡ Π² ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅ ΡΠ°Π±ΠΎΡΡ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΠΉ.
@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;
}
}
ΠΠ°ΡΡΡΠΎΠΉΠΊΠ°
ΠΠ»Ρ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΡ ΠΊ AMQ Online Π½Π°ΡΠ΅ΠΌΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡΡΡ Π½Π΅ΠΊΠΎΡΠΎΡΡΠ΅ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅, Π° ΠΈΠΌΠ΅Π½Π½ΠΎ: ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ Quarkus-ΠΊΠΎΠ½Π½Π΅ΠΊΡΠΎΡΠ°, ΡΠ²Π΅Π΄Π΅Π½ΠΈΡ ΠΎ ΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠΉ ΡΠΎΡΠΊΠ΅ AMQP ΠΈ ΠΊΠ»ΠΈΠ΅Π½ΡΡΠΊΠΈΠ΅ ΡΡΠ΅ΡΠ½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅. ΠΡΡΡΠ΅, ΠΊΠΎΠ½Π΅ΡΠ½ΠΎ, Π΄Π΅ΡΠΆΠ°ΡΡ Π²ΡΠ΅ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΌΠ΅ΡΡΠ΅, Π½ΠΎ ΠΌΡ ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΠΎ ΡΠ°Π·Π΄Π΅Π»ΠΈΠΌ ΠΈΡ , ΡΡΠΎΠ±Ρ ΠΏΠΎΠΊΠ°Π·Π°ΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΠ΅ Π²Π°ΡΠΈΠ°Π½ΡΡ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Quarkus.
ΠΠΎΠ½Π½Π΅ΠΊΡΠΎΡΡ
ΠΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ ΠΊΠΎΠ½Π½Π΅ΠΊΡΠΎΡΠ° ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²ΠΈΡΡ Π½Π° ΡΡΠ°ΠΏΠ΅ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΠ°ΠΉΠ»Π° ΡΠ²ΠΎΠΉΡΡΠ² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ:
mp.messaging.outgoing.orders.connector=smallrye-amqp
mp.messaging.incoming.orders.connector=smallrye-amqp
Π§ΡΠΎΠ±Ρ Π½Π΅ ΡΡΠ»ΠΎΠΆΠ½ΡΡΡ, ΠΌΡ Π±ΡΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΎΡΠ΅ΡΠ΅Π΄Ρ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΡΠΎΠ»ΡΠΊΠΎ Π΄Π»Ρ Π°Π΄ΡΠ΅ΡΠ° Β«ordersΒ». Π Π°Π΄ΡΠ΅Ρ Β«confirmationsΒ» Π² Π½Π°ΡΠ΅ΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ Π±ΡΠ΄Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΎΡΠ΅ΡΠ΅Π΄Ρ Π² ΠΏΠ°ΠΌΡΡΠΈ.
ΠΠΎΠ½Π΅ΡΠ½Π°Ρ ΡΠΎΡΠΊΠ° AMQP
ΠΠ° ΡΡΠ°ΠΏΠ΅ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ ΠΈΠΌΡ Ρ ΠΎΡΡΠ° ΠΈ Π½ΠΎΠΌΠ΅Ρ ΠΏΠΎΡΡΠ° Π΄Π»Ρ ΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠΉ ΡΠΎΡΠΊΠΈ AMQP Π½Π΅ΠΈΠ·Π²Π΅ΡΡΠ½Ρ, ΠΏΠΎΡΡΠΎΠΌΡ ΠΈΡ Π½ΡΠΆΠ½ΠΎ Π²Π½Π΅Π΄ΡΠΈΡΡ. ΠΠΎΠ½Π΅ΡΠ½ΡΡ ΡΠΎΡΠΊΡ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π΄Π°ΡΡ Π² configmap, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ AMQ Online, ΠΏΠΎΡΡΠΎΠΌΡ ΠΌΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΠΌ ΠΈΡ ΡΠ΅ΡΠ΅Π· ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΡΡΠ΅Π΄Ρ Π² ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ:
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
Π£ΡΠ΅ΡΠ½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅
ΠΠ°ΡΠΊΠ΅Ρ ΡΡΠ΅ΡΠ½ΠΎΠΉ Π·Π°ΠΏΠΈΡΠΈ ΡΠ΅ΡΠ²ΠΈΡΠ° ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΄Π»Ρ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π² OpenShift. ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ Π½Π°Π΄ΠΎ ΡΠ½Π°ΡΠ°Π»Π° ΡΠΎΠ·Π΄Π°ΡΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠΉ ConfigSource, ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ ΡΠΈΡΠ°ΡΡ ΠΌΠ°ΡΠΊΠ΅Ρ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ ΠΈΠ· ΡΠ°ΠΉΠ»ΠΎΠ²ΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΡ podβΠ°:
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);
}
}
Π‘Π±ΠΎΡΠΊΠ° ΠΈ ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ
ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π°Π΄ΠΎ ΡΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΠΎΠ²Π°ΡΡ Π² ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΠΉ ΡΠ°ΠΉΠ», ΠΏΠΎΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π²ΠΈΡΡΡΠ°Π»ΡΠ½Π°Ρ ΠΌΠ°ΡΠΈΠ½Π° GraalVM. ΠΠΎΠ΄ΡΠΎΠ±Π½Π΅Π΅ ΠΎ ΡΠΎΠΌ, ΠΊΠ°ΠΊ Π½Π°ΡΡΡΠΎΠΈΡΡ Π΄Π»Ρ ΡΡΠΎΠ³ΠΎ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΠ΅, ΡΠΌ. ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠ΅ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ Π²
ΠΠ°ΡΠ΅ΠΌ, ΡΠ»Π΅Π΄ΡΡ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Π½ΡΠΌ ΡΠ°ΠΌ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΡΠΌ, Π½Π°Π΄ΠΎ ΡΠΊΠ°ΡΠ°ΡΡ ΠΈΡΡ ΠΎΠ΄Π½ΠΈΠΊ, ΠΏΡΠΎΠ²Π΅ΡΡΠΈ ΡΠ±ΠΎΡΠΊΡ ΠΈ Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡ ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΠ΅ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ:
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
ΠΠΎΡΠ»Π΅ ΡΡΠΈΡ ΠΊΠΎΠΌΠ°Π½Π΄ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π±ΡΠ΄Π΅Ρ ΡΠ°Π·Π²Π΅ΡΠ½ΡΡΠΎ, Π½ΠΎ Π½Π΅ Π·Π°ΠΏΡΡΡΠΈΡΡΡ Π΄ΠΎ ΡΠ΅Ρ ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° ΠΌΡ Π½Π΅ Π½Π°ΡΡΡΠΎΠΈΠΌ Π² AMQ Online Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΠ΅ Π½Π°ΠΌ ΡΠ΅ΡΡΡΡΡ ΠΎΠ±ΠΌΠ΅Π½Π° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΠΌΠΈ.
ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° ΡΠΈΡΡΠ΅ΠΌΡ ΠΎΠ±ΠΌΠ΅Π½Π° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΠΌΠΈ
Π’Π΅ΠΏΠ΅ΡΡ ΠΎΡΡΠ°Π»ΠΎΡΡ Π·Π°Π΄Π°ΡΡ Π² ΡΠΈΡΡΠ΅ΠΌΠ΅ ΠΎΠ±ΠΌΠ΅Π½Π° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΠΌΠΈ ΡΠ΅ΡΡΡΡΡ, ΠΊΠΎΡΠΎΡΡΠ΅ Π½ΡΠΆΠ½Ρ Π½Π°ΡΠ΅ΠΌΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ Π½Π°Π΄ΠΎ ΡΠΎΠ·Π΄Π°ΡΡ: 1) Π°Π΄ΡΠ΅ΡΠ½ΠΎΠ΅ ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²ΠΎ, ΡΡΠΎΠ±Ρ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ ΠΊΠΎΠ½Π΅ΡΠ½ΡΡ ΡΠΎΡΠΊΡ ΡΠΈΡΡΠ΅ΠΌΡ ΠΎΠ±ΠΌΠ΅Π½Π° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΠΌΠΈ; 2) Π°Π΄ΡΠ΅Ρ, ΡΡΠΎΠ±Ρ Π½Π°ΡΡΡΠΎΠΈΡΡ Π°Π΄ΡΠ΅ΡΠ°, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ Π² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ; 3) ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ ΡΠΈΡΡΠ΅ΠΌΡ ΠΎΠ±ΠΌΠ΅Π½Π° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΠΌΠΈ, ΡΡΠΎΠ±Ρ Π·Π°Π΄Π°ΡΡ ΡΡΠ΅ΡΠ½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ ΠΊΠ»ΠΈΠ΅Π½ΡΠ°.
ΠΡΠΎΡΡΡΠ°Π½ΡΡΠ²ΠΎ Π°Π΄ΡΠ΅ΡΠΎΠ²
ΠΠ±ΡΠ΅ΠΊΡ AddressSpace Π² AMQ Online β ΡΡΠΎ Π³ΡΡΠΏΠΏΠ° Π°Π΄ΡΠ΅ΡΠΎΠ², ΠΊΠΎΡΠΎΡΡΠ΅ ΡΠΎΠ²ΠΌΠ΅ΡΡΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ ΠΊΠΎΠ½Π΅ΡΠ½ΡΠ΅ ΡΠΎΡΠΊΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΡ, Π° ΡΠ°ΠΊΠΆΠ΅ ΠΏΠΎΠ»ΠΈΡΠΈΠΊΠΈ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ ΠΈ Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΠΈ. ΠΡΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΠΈ ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π° Π°Π΄ΡΠ΅ΡΠΎΠ² ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π΄Π°ΡΡ, ΠΊΠ°ΠΊ ΠΈΠΌΠ΅Π½Π½ΠΎ Π±ΡΠ΄ΡΡ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΡΡΡΡ ΠΊΠΎΠ½Π΅ΡΠ½ΡΠ΅ ΡΠΎΡΠΊΠΈ ΡΠΈΡΡΠ΅ΠΌΡ ΠΎΠ±ΠΌΠ΅Π½Π° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΠΌΠΈ:
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
ΠΠ΄ΡΠ΅ΡΠ°
ΠΠ΄ΡΠ΅ΡΠ° ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ Π΄Π»Ρ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΠΈ ΠΏΡΠΈΠ΅ΠΌΠ° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ. Π£ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π°Π΄ΡΠ΅ΡΠ° Π΅ΡΡΡ ΡΠΈΠΏ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ Π΅Π³ΠΎ ΡΠ΅ΠΌΠ°Π½ΡΠΈΠΊΡ, Π° ΡΠ°ΠΊΠΆΠ΅ ΠΏΠ»Π°Π½, ΠΊΠΎΡΠΎΡΡΠΉ Π·Π°Π΄Π°Π΅Ρ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠ΅Π·Π΅ΡΠ²ΠΈΡΡΠ΅ΠΌΡΡ ΡΠ΅ΡΡΡΡΠΎΠ². ΠΠ΄ΡΠ΅Ρ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π²ΠΎΡ ΡΠ°ΠΊ:
apiVersion: enmasse.io/v1beta1
kind: Address
metadata:
name: quarkus-example.orders
spec:
address: orders
type: queue
plan: brokered-queue
ΠΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ ΡΠΈΡΡΠ΅ΠΌΡ ΠΎΠ±ΠΌΠ΅Π½Π° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΠΌΠΈ
Π§ΡΠΎΠ±Ρ ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡ ΠΈ ΠΏΠΎΠ»ΡΡΠ°ΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ Π½Π° Π²Π°ΡΠΈ Π°Π΄ΡΠ΅ΡΠ° ΠΌΠΎΠ³Π»ΠΈ ΡΠΎΠ»ΡΠΊΠΎ Π΄ΠΎΠ²Π΅ΡΠ΅Π½Π½ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, Π² ΡΠΈΡΡΠ΅ΠΌΠ΅ ΠΎΠ±ΠΌΠ΅Π½Π° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΠΌΠΈ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΎΠ·Π΄Π°ΡΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ. ΠΠ»Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, ΡΠ°Π±ΠΎΡΠ°ΡΡΠΈΡ Π½Π° ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅, ΠΊΠ»ΠΈΠ΅Π½ΡΠΎΠ² ΠΌΠΎΠΆΠ½ΠΎ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΡΠΈΡΠΎΠ²Π°ΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΡΠ΅ΡΠ½ΠΎΠΉ Π·Π°ΠΏΠΈΡΠΈ ΡΠ΅ΡΠ²ΠΈΡΠ° OpenShift. ΠΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Β«serviceaccountΒ» ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΠ°ΠΊ:
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"]
Π Π°Π·ΡΠ΅ΡΠ΅Π½ΠΈΡ Π΄Π»Ρ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ
Π§ΡΠΎΠ±Ρ AMQ Online ΠΌΠΎΠ³ ΡΠΎΠ·Π΄Π°ΡΡ configmap, ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΠΈ Π΄Π»Ρ Π²Π½Π΅Π΄ΡΠ΅Π½ΠΈΡ ΡΠ²Π΅Π΄Π΅Π½ΠΈΠΉ ΠΎ ΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠΉ ΡΠΎΡΠΊΠ΅ AMQP, Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π·Π°Π΄Π°ΡΡ ΡΠΎΠ»Ρ ΠΈ ΠΏΡΠΈΠ²ΡΠ·ΠΊΡ ΡΠΎΠ»ΠΈ (Role ΠΈ RoleBinding):
---
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
ΠΠ°ΠΊ ΠΏΡΠΈΠΌΠ΅Π½ΠΈΡΡ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ
ΠΡΠΈΠΌΠ΅Π½ΠΈΡΡ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ ΡΠΈΡΡΠ΅ΠΌΡ ΠΎΠ±ΠΌΠ΅Π½Π° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΠΌΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π²ΠΎΡ ΡΠ°ΠΊ:
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
ΠΠ΅ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ
Π§ΡΠΎΠ±Ρ ΡΠ±Π΅Π΄ΠΈΡΡΡΡ, ΡΡΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π·Π°ΠΏΡΡΡΠΈΠ»ΠΎΡΡ, ΠΏΠ΅ΡΠ²ΡΠΌ Π΄Π΅Π»ΠΎΠΌ ΠΏΡΠΎΠ²Π΅ΡΠΈΠΌ, ΡΠΎΠ·Π΄Π°Π»ΠΈΡΡ Π»ΠΈ ΠΈ Π°ΠΊΡΠΈΠ²Π½Ρ Π»ΠΈ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠ΅ Π°Π΄ΡΠ΅ΡΠ°:
until [[ `oc get address quarkus-example.prices -o jsonpath='{.status.phase}'` == "Active" ]]; do echo "Not yet ready"; sleep 5; done
ΠΠ°ΡΠ΅ΠΌ ΠΏΡΠΎΠ²Π΅ΡΠΈΠΌ URL ΠΌΠ°ΡΡΡΡΡΠ° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ (ΠΏΡΠΎΡΡΠΎ ΠΎΡΠΊΡΠΎΠ΅ΠΌ ΡΡΠΎ Π°Π΄ΡΠ΅Ρ Π² Π±ΡΠ°ΡΠ·Π΅ΡΠ΅):
echo "http://$(oc get route quarkus-example-client -o jsonpath='{.spec.host}')/prices.html"
Π Π±ΡΠ°ΡΠ·Π΅ΡΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±ΡΡΡ Π²ΠΈΠ΄Π½ΠΎ, ΡΡΠΎ ΡΠΈΠΊΠ΅ΡΡ ΠΏΠ΅ΡΠΈΠΎΠ΄ΠΈΡΠ΅ΡΠΊΠΈ ΠΎΠ±Π½ΠΎΠ²Π»ΡΡΡΡΡ ΠΏΠΎ ΠΌΠ΅ΡΠ΅ ΡΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡΡΡ ΠΈ ΠΏΡΠΈΠ½ΠΈΠΌΠ°ΡΡΡΡ AMQ Online.
ΠΠΎΠ΄Π²ΠΎΠ΄ΠΈΠΌ ΠΈΡΠΎΠ³ΠΈ
ΠΡΠ°ΠΊ, ΠΌΡ Π½Π°ΠΏΠΈΡΠ°Π»ΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Quarkus, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΠ΅Π΅ AMQP Π΄Π»Ρ ΠΎΠ±ΠΌΠ΅Π½Π° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΠΌΠΈ, Π½Π°ΡΡΡΠΎΠΈΠ»ΠΈ ΡΡΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Π½Π° ΠΏΠ»Π°ΡΡΠΎΡΠΌΠ΅ Red Hat OpenShift, Π° ΡΠ°ΠΊΠΆΠ΅ Π²Π½Π΅Π΄ΡΠΈΠ»ΠΈ Π΅Π³ΠΎ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ AMQ Online. ΠΠ°ΡΠ΅ΠΌ ΠΌΡ ΡΠΎΠ·Π΄Π°Π»ΠΈ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΡ, Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΠ΅ Π΄Π»Ρ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΡΠΈΡΡΠ΅ΠΌΡ ΠΎΠ±ΠΌΠ΅Π½Π° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΠΌΠΈ ΠΏΠΎΠ΄ Π½Π°ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅.
ΠΠ° ΡΡΠΎΠΌ ΠΌΡ Π·Π°Π²Π΅ΡΡΠ°Π΅ΠΌ ΡΠ΅ΡΠΈΡ ΠΏΡΠΎ Quarkus, Π½ΠΎ Π²ΠΏΠ΅ΡΠ΅Π΄ΠΈ ΠΌΠ½ΠΎΠ³ΠΎ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΈ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΎΠ³ΠΎ, ΠΎΡΡΠ°Π²Π°ΠΉΡΠ΅ΡΡ Ρ Π½Π°ΠΌΠΈ!
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com