ΠΠ΄ΡΠ°Π²Π΅ΠΉΡΠ΅ Π²ΡΠΈΡΠΊΠΈ! ΠΡΠΎ Π³ΠΎ ΠΈ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΡΡ Π½ΠΈ ΠΏΠΎΡΡ ΠΎΡ ΠΏΠΎΡΠ΅Π΄ΠΈΡΠ°ΡΠ° Quarkus! (ΠΠ΅ΠΆΠ΄Ρ Π΄ΡΡΠ³ΠΎΡΠΎ, Π³Π»Π΅Π΄Π°ΠΉΡΠ΅ Π½Π°ΡΠΈΡ ΡΠ΅Π±ΠΈΠ½Π°Ρ
Π
ΠΡ Π²Π΅ΡΡΠΈΡ 0.17.0,
ΠΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π° ΡΠ΅, ΡΠ΅ Π²Π΅ΡΠ΅ ΡΡΠ΅ ΡΠ°Π·ΠΏΠΎΠ»ΠΎΠΆΠΈΠ»ΠΈ AMQ Online Π½Π° ΠΏΠ»Π°ΡΡΠΎΡΠΌΠ°ΡΠ° OpenShift (Π°ΠΊΠΎ Π½Π΅, Π²ΠΈΠΆΡΠ΅
ΠΠ°ΡΠΎ Π½Π°ΡΠ°Π»ΠΎ ΡΠ΅ ΡΡΠ·Π΄Π°Π΄Π΅ΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Quarkus, ΠΊΠΎΠ΅ΡΠΎ ΡΠ΅ Π±ΡΠ΄Π΅ ΠΏΡΠΎΡΡΠ° ΡΠΈΡΡΠ΅ΠΌΠ° Π·Π° ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π½Π° ΠΏΠΎΡΡΡΠΊΠΈ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ° ΡΠ΅Π°ΠΊΡΠΈΠ²Π½ΠΈ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ. Π’ΠΎΠ²Π° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΠ΅ Π²ΠΊΠ»ΡΡΠ²Π° Π³Π΅Π½Π΅ΡΠ°ΡΠΎΡ Π½Π° ΠΏΠΎΡΡΡΠΊΠΈ, ΠΊΠΎΠΉΡΠΎ ΠΈΠ·ΠΏΡΠ°ΡΠ° ΠΏΠΎΡΡΡΠΊΠΈ ΠΊΡΠΌ ΠΎΠΏΠ°ΡΠΊΠ° ΠΎΡ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ Π½Π° ΡΠΈΠΊΡΠΈΡΠ°Π½ ΠΈΠ½ΡΠ΅ΡΠ²Π°Π», ΠΊΠ°ΠΊΡΠΎ ΠΈ ΠΏΡΠΎΡΠ΅ΡΠΎΡ Π·Π° ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π½Π° ΠΏΠΎΡΡΡΠΊΠΈ, ΠΊΠΎΠΉΡΠΎ ΡΠ΅ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ²Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΎΡ ΠΎΠΏΠ°ΡΠΊΠ°ΡΠ° ΠΈ ΡΠ΅ Π³Π΅Π½Π΅ΡΠΈΡΠ° ΠΏΠΎΡΠ²ΡΡΠΆΠ΄Π΅Π½ΠΈΡ, Π²ΠΈΠ΄ΠΈΠΌΠΈ Π² Π±ΡΠ°ΡΠ·ΡΡΠ°.
Π‘Π»Π΅Π΄ ΠΊΠ°ΡΠΎ ΡΡΠ·Π΄Π°Π΄Π΅ΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ, ΡΠ΅ Π²ΠΈ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ ΠΊΠ°ΠΊ Π΄Π° Π²Π³ΡΠ°Π΄ΠΈΡΠ΅ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡΡΠ° Π½Π° ΡΠΈΡΡΠ΅ΠΌΠ°ΡΠ° Π·Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ Π² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ ΠΈ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ΅ AMQ Online, Π·Π° Π΄Π° ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²ΠΈΠΌ ΡΠ΅ΡΡΡΡΠΈΡΠ΅, ΠΎΡ ΠΊΠΎΠΈΡΠΎ ΡΠ΅ Π½ΡΠΆΠ΄Π°Π΅ΠΌ Π² ΡΠΈΡΡΠ΅ΠΌΠ°ΡΠ°.
ΠΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Quarkus
ΠΠ°ΡΠ΅ΡΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Quarkus ΡΠ°Π±ΠΎΡΠΈ Π½Π° OpenShift ΠΈ Π΅ ΠΌΠΎΠ΄ΠΈΡΠΈΡΠΈΡΠ°Π½Π° Π²Π΅ΡΡΠΈΡ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°
ΠΠ΅Π½Π΅ΡΠ°ΡΠΎΡ Π½Π° ΠΏΠΎΡΡΡΠΊΠΈ
ΠΠ΅Π½Π΅ΡΠ°ΡΠΎΡΡΡ ΠΏΡΠΎΡΡΠΎ ΠΌΠΎΠ½ΠΎΡΠΎΠ½Π½ΠΎ ΠΈΠ·ΠΏΡΠ°ΡΠ° Π½Π°ΡΠ°ΡΡΠ²Π°ΡΠΈ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΈ Π½Π° ΠΏΠΎΡΡΡΠΊΠΈ Π΄ΠΎ Π°Π΄ΡΠ΅ΡΠ° Π½Π° βΠΏΠΎΡΡΡΠΊΠΈβ Π½Π° Π²ΡΠ΅ΠΊΠΈ 5 ΡΠ΅ΠΊΡΠ½Π΄ΠΈ.
@ApplicationScoped
public class OrderGenerator {
private int orderId = 1;
@Outgoing("orders")
public Flowable<Integer> generate() {
return Flowable.interval(5, TimeUnit.SECONDS)
.map(tick -> orderId++);
}
}
ΠΡΠΎΡΠ΅ΡΠΎΡ Π½Π° ΠΏΠΎΡΡΡΠΊΠΈ
ΠΠ°Π½ΠΈΠΏΡΠ»Π°ΡΠΎΡΡΡ Π½Π° ΠΏΠΎΡΡΡΠΊΠΈΡΠ΅ Π΅ ΠΎΡΠ΅ ΠΏΠΎ-ΠΏΡΠΎΡΡ, ΡΠΎΠΉ ΠΏΡΠΎΡΡΠΎ Π²ΡΡΡΠ° ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ Π·Π° ΠΏΠΎΡΠ²ΡΡΠΆΠ΄Π΅Π½ΠΈΠ΅ Π½Π° Π°Π΄ΡΠ΅ΡΠ° Π·Π° βΠΏΠΎΡΠ²ΡΡΠΆΠ΄Π΅Π½ΠΈΡβ.
@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
ΠΠ° Π΄Π° ΠΎΠΏΡΠΎΡΡΠΈΠΌ Π½Π΅ΡΠ°ΡΠ°, ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΎΠΏΠ°ΡΠΊΠ° ΠΎΡ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ ΡΠ°ΠΌΠΎ Π·Π° Π°Π΄ΡΠ΅ΡΠ° Π½Π° βΠΏΠΎΡΡΡΠΊΠΈβ. Π Π°Π΄ΡΠ΅ΡΡΡ Π·Π° βΠΏΠΎΡΠ²ΡΡΠΆΠ΄Π΅Π½ΠΈΡβ Π² Π½Π°ΡΠ΅ΡΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΎΠΏΠ°ΡΠΊΠ° Π² ΠΏΠ°ΠΌΠ΅ΡΡΠ°.
ΠΡΠ°ΠΉΠ½Π° ΡΠΎΡΠΊΠ° Π½Π° AMQP
ΠΠΎ Π²ΡΠ΅ΠΌΠ΅ Π½Π° ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΠ°Π½Π΅ ΠΈΠΌΠ΅ΡΠΎ Π½Π° Ρ ΠΎΡΡΠ° ΠΈ Π½ΠΎΠΌΠ΅ΡΡΡ Π½Π° ΠΏΠΎΡΡΠ° Π·Π° ΠΊΡΠ°ΠΉΠ½Π°ΡΠ° ΡΠΎΡΠΊΠ° Π½Π° AMQP ΡΠ° Π½Π΅ΠΈΠ·Π²Π΅ΡΡΠ½ΠΈ, ΡΠ°ΠΊΠ° ΡΠ΅ ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π°Ρ ΠΈΠ½ΠΆΠ΅ΠΊΡΠΈΡΠ°Π½ΠΈ. ΠΡΠ°ΠΉΠ½Π°ΡΠ° ΡΠΎΡΠΊΠ° ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ Π·Π°Π΄Π°Π΄Π΅Π½Π° Π² ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½Π°ΡΠ° ΠΊΠ°ΡΡΠ°, ΠΊΠΎΡΡΠΎ Π΅ ΡΡΠ·Π΄Π°Π΄Π΅Π½Π° ΠΎΡ 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, Π½ΠΎ ΠΏΡΠ΅Π΄ΡΡΠΎΡΡ ΠΌΠ½ΠΎΠ³ΠΎ Π½ΠΎΠ²ΠΈ ΠΈ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΈ Π½Π΅ΡΠ°, ΠΎΡΠ°ΠΊΠ²Π°ΠΉΡΠ΅!
ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: www.habr.com