@@ -24,252 +24,41 @@ Schaue im Jenkins nach, ob alle Pipelines durchgelaufen sind.
2424Wenn die vier Services deployt sind, kann die Swagger-UI des Customer Services auf dem Testsystem
2525über folgende URL erreicht werden: [ Customer-Service] ( http://localhost:8281 )
2626
27- ## Übung 1 - Verwendung des Pact-Brokers
28-
29- Der Pact Broker ist bisher (außer eines Sample Contracts) leer.
30-
31- Wir wollen jetzt, dass die Services ihre Contracts via Pact austauschen.
32- Dazu muss in allen vier Services der Branch ` pact-broker `
33- in den Branch ` develop ` gemergt werden.
34- Gehe auf den Git-Server und erstelle zunächst im ` customer-service `
35- einen Pull-Request mit dem Base-Branch ` develop `
36- und dem Vergleichs-Branch ` pact-broker ` und führe diese dann zusammen.
37- Die Jenkins-Pipeline sollte nun automatisch anfangen zu bauen
38- und den neuen Stand des Customer Services auf das Testsystem deployen.
39-
40- Wenn das geschehen ist, kannst du im Pact-Broker sehen,
41- dass vom Customer Service zwei Contracts hochgeladen wurden,
42- einer für den Billing Service und einer für den Delivery Service.
43- Beide Contracts sind allerdings noch nicht verifiziert.
44-
45- Wir mergen nun im Billing Service den Branch ` pact-broker ` in den Branch ` develop ` .
46- Dazu erstellen wir wieder, wie oben beschrieben, einen Pull-Request
47- und führen ihn zusammen.
48-
49- Nachdem wir beobachtet haben, dass der Billing Service gebaut
50- und deployt wurde, können wir im Pact Broker sehen,
51- dass der Billing Service den Contract des Customer Services verifiziert hat.
52-
53- Wir mergen nun analog den Delivery Service und beobachten auch hier,
54- dass er den Contract verifiziert.
55-
56- Eine weitere Beobachtung wird sein,
57- dass der Delivery Service einen weiteren Contract hochgeladen hat,
58- nämlich für den Address Validation Service.
59-
60- Zu guter Letzt mergen wir also den Branch ` pact-broker `
61- auch im Address Validation Service in den Branch ` develop `
62- und beobachten auch hier die Verifizierung.
63-
64- ## Übung 2 - Nur deployen, wenn der Branch verifiziert ist.
65-
66- Es wäre wünschenswert, dass ein Service nur deployt wird,
67- wenn seine Contracts auch von den jeweiligen Providern verifiziert wurden.
68- Um das zu erreichen, müssen wir die Pipelines so umbauen,
69- dass die Consumer die Pipelines der Provider immer dann antriggern,
70- wenn sie einen neuen Contract hochgeladen haben.
71-
72- Zunächst müssen wir allerdings die Provider-Pipelines so umbauen,
73- dass sie dann auch nur die Contracts verifizieren (und nicht selber deployen).
74- Dazu mergen wir zunächst im Address Validation Service und im Billing Service
75- jeweils den Branch ` pipeline ` in den Branch ` develop ` .
76-
77- Ist das geschehen (und das jeweilige Build erfolgreich durchgelaufen),
78- können wir zunächst im Delivery Service den Branch ` pipeline ` in den Branch ` develop ` mergen.
79- Danach können wir beobachten, wie der Build des Delivery Services
80- den Build des Address Validation Services anstößt, dieser nur bis zur Phase Test baut
81- (und den Contract verifiziert) und dann der Build des Delivery Services fortgesetzt wird.
82-
83- Anschließend können wir dasselbe im Customer Service beobachten,
84- wenn wir auch hier den Branch ` pipeline ` nach ` develop ` mergen.
85- Hier lässt sich beobachten, dass sowohl der Build des Billing Services
86- als auch der Build des Delivery Services angestoßen wird.
87-
88- ## Übung 3 - Verifizieren der Contracts von unterschiedlichen Stages
89-
90- Um sicherzustellen, dass alle Versionen einer Stage zusammenpassen,
91- gibt es in Pact das Konzept der Branches und Environments.
92-
93- Sobald ein Service in einer Version auf einer Stage deployt worden ist,
94- kann diese Version im Pact-Broker mit Tags für Branch und Environment (Stage) versehen werden.
95-
96- Wir können das sehen, indem wir sowohl im Address Validation Service
97- als auch im Billing Service jeweils den Branch ` pact-tags ` in den Branch ` develop ` mergen.
98- Nach erfolgreichem Deployment sind die jeweiligen Versionen im Pact Broker jeweils mit
99- Branch ` develop ` und Environment ` test ` getaggt.
100-
101- Wenn wir nun im Delivery Service den Branch ` pact-tags ` in ` develop ` mergen,
102- wird der Delivery Service im Pact Broker für den Contract mit dem Address Validation
103- Service mit dem Branch ` develop ` getaggt. In der Pipeline können wir beobachten, dass
104- versucht wird, die Pipeline des Address Validation Services zu starten. Wir merken jedoch,
105- dass sich da nichts tut. Das Problem ist, dass per Default in unserer Jenkins-Instanz
106- nur ein Build-Prozessor aktiv ist. Daher müssen wir in den Systemeinstellungen die Anzahl
107- der Build-Prozessoren auf 2 hochsetzen. Anschließend können wir beobachten, dass die Pipeline
108- des Address Validation Services parallel zu starten beginnt. Der Service verwendet beim
109- Verifizieren des Contracts die Version, die auch auf der Stage deployt ist, auf die der
110- Delivery Service deployen möchte (in diesem Fall die Test-Stage). Nachdem der Address Validation
111- Service den Contract verifiziert hat, darf der Delivery Services deployen und taggt seine Seite
112- des Contracts mit dem Environment ` test ` .
113-
114- Dasselbe können wir erneut beim Customer Service beobachten,
115- wenn wir auch hier den Branch ` pact-tags ` in den Branch ` develop ` mergen.
116-
117- ## Übung 4 - Unabhängige Pipelines
118-
119- Bisher ist es so, dass die Abhängigkeiten zwischen den Pipelines explizit
120- im ` Jenkinsfile ` eingetragen sind.
121- In der Praxis ist das nicht immer möglich.
122- Wenn Services von unterschiedlichen Teams umgesetzt werden und eventuell
123- sogar auf unterschiedlichen Build-Servern laufen,
124- werden andere Mechanismen benötigt, um die Verifikation von Contracts anzustoßen.
125-
126- Der Pact Broker bietet hierzu die Möglichkeit,
127- zwei Arten von Webhooks zu registrieren.
128- Einerseits kann man einen Webhook registrieren,
129- der aufgerufen wird, wenn ein Contract hochgeladen wird.
130- Andererseits kann man einen Webhook registrieren,
131- der aufgerufen wird, wenn ein Contract verifiziert
132- und das Ergebnis hochgeladen wurde.
133- Ersteren werden wir verwenden, um die Verifikation anzustoßen.
134-
135- Wir können die Webhooks registrieren, indem wir im Pact-Broker rechts oben
136- auf den ` API Browser ` gehen.
137- Dort suchen wir die Ressource ` pb:webhooks ` und klicken auf ` Perform non-GET request ` .
138- Das ist das gelb unterlegte ` ! ` .
139-
140- Insgesamt wollen wir fünf Webhooks anlegen:
141- zunächst einmal drei zum Antriggern der Verifikation
142- (nämlich für den Billing Service, den Delivery Service und den Address Validation Service).
143- Dazu führen wir drei POST-Requests mit den folgenden Bodys aus:
144-
145- ```
146- {
147- "provider": {
148- "name": "billing-service"
149- },
150- "events": [{
151- "name": "contract_requiring_verification_published"
152- }],
153- "request": {
154- "method": "GET",
155- "url": "http://jenkins:8080/generic-webhook-trigger/invoke?token=billing-service&branch=${pactbroker.consumerVersionBranch}&verifyPacts=true",
156- "headers": {
157- },
158- "body": {
159- "event_type": "contract_requiring_verification_published",
160- "client_payload": {
161- "pact_url": "${pactbroker.pactUrl}",
162- "sha": "${pactbroker.providerVersionNumber}",
163- "branch": "${pactbroker.providerVersionBranch}",
164- "message": "Verify changed pact for ${pactbroker.consumerName} version ${pactbroker.consumerVersionNumber} branch ${pactbroker.consumerVersionBranch} by ${pactbroker.providerVersionNumber} (${pactbroker.providerVersionDescriptions})"
165- }
166- }
167- }
168- }
169- ```
170-
171- ```
172- {
173- "provider": {
174- "name": "delivery-service"
175- },
176- "events": [{
177- "name": "contract_requiring_verification_published"
178- }],
179- "request": {
180- "method": "GET",
181- "url": "http://jenkins:8080/generic-webhook-trigger/invoke?token=delivery-service&branch=${pactbroker.consumerVersionBranch}&verifyPacts=true",
182- "headers": {
183- },
184- "body": {
185- "event_type": "contract_requiring_verification_published",
186- "client_payload": {
187- "pact_url": "${pactbroker.pactUrl}",
188- "sha": "${pactbroker.providerVersionNumber}",
189- "branch": "${pactbroker.providerVersionBranch}",
190- "message": "Verify changed pact for ${pactbroker.consumerName} version ${pactbroker.consumerVersionNumber} branch ${pactbroker.consumerVersionBranch} by ${pactbroker.providerVersionNumber} (${pactbroker.providerVersionDescriptions})"
191- }
192- }
193- }
194- }
195- ```
196-
197- ```
198- {
199- "provider": {
200- "name": "address-validation-service"
201- },
202- "events": [{
203- "name": "contract_requiring_verification_published"
204- }],
205- "request": {
206- "method": "GET",
207- "url": "http://jenkins:8080/generic-webhook-trigger/invoke?token=address-validation-service&branch=${pactbroker.consumerVersionBranch}&verifyPacts=true",
208- "headers": {
209- },
210- "body": {
211- "event_type": "contract_requiring_verification_published",
212- "client_payload": {
213- "pact_url": "${pactbroker.pactUrl}",
214- "sha": "${pactbroker.providerVersionNumber}",
215- "branch": "${pactbroker.providerVersionBranch}",
216- "message": "Verify changed pact for ${pactbroker.consumerName} version ${pactbroker.consumerVersionNumber} branch ${pactbroker.consumerVersionBranch} by ${pactbroker.providerVersionNumber} (${pactbroker.providerVersionDescriptions})"
217- }
218- }
219- }
220- }
221- ```
222-
223- Außerdem legen wir mit weiteren POST-Requests noch zwei Webhooks an, die getriggert werden, wenn eine Verifikation erfolgreich war
224- und der Service auf die Stage deployen kann. Diese brauchen wir für den Customer Service und den Delivery Service.
225-
226- ```
227- {
228- "consumer": {
229- "name": "customer-service"
230- },
231- "events": [{
232- "name": "provider_verification_published"
233- }],
234- "request": {
235- "method": "GET",
236- "url": "http://jenkins:8080/generic-webhook-trigger/invoke?token=customer-service&branch=${pactbroker.consumerVersionBranch}&deployOnly=true&deploymentVersion=${pactbroker.consumerVersionNumber}",
237- "headers": {
238- }
239- }
240- }
241- ```
242-
243- ```
244- {
245- "consumer": {
246- "name": "delivery-service"
247- },
248- "events": [{
249- "name": "provider_verification_published"
250- }],
251- "request": {
252- "method": "GET",
253- "url": "http://jenkins:8080/generic-webhook-trigger/invoke?token=delivery-service&branch=${pactbroker.consumerVersionBranch}&deployOnly=true&deploymentVersion=${pactbroker.consumerVersionNumber}",
254- "headers": {
255- }
256- }
257- }
258- ```
259-
260- Wenn wir alle Webhooks angelegt haben, können wir das Ganze testen,
261- indem wir jeweils die Branches ` webhook ` in den Branch ` main ` mergen.
262-
263- Zunächst tun wir das für den Billing Service und den Address Validation Service und warten,
264- bis diese auf dem Produktivsystem deployt sind.
265-
266- Danach mergen wir den Branch im Delivery Service. Nun können wir beobachten,
267- wie der Delivery Service gebaut und gepusht wird, aber noch nicht deployt wird,
268- weil sein hochgeladener Contract noch nicht für die Production Stage verifiziert ist.
269- Das Hochladen des Contracts hat aber bereits den Address Validation Service angestoßen,
270- der die Verifikation vornimmt. Sobald der Address Validation Service den Contract verifiziert hat,
271- wird über den Webhook wieder der Delivery Service angestoßen, der jetzt nur noch deployt.
272-
273- Wenn wir im Customer Service auch den Branch ` webhook ` nach ` main ` mergen,
274- können wir hier dasselbe beobachten, nur dass der Customer Service die Verifikation
275- in Billing Service und Delivery Service anstößst und auch auf beide Verifikationen wartet.
27+ ## Übung: Consumer-Driven Contract Tests schreiben
28+
29+ Im ` customer-service ` liegt bereits eine Testklasse ` DeliveryAddressRepositoryTest ` ,
30+ die Consumer-Driven Contract Tests mit Pact für den Delivery Service definiert.
31+ Die Tests sind jedoch noch unvollständig: Requests und Responses enthalten noch keine Bodies,
32+ und ein Statuscode ist falsch gesetzt.
33+
34+ Vervollständige die Pact-Consumer-Tests in der Klasse
35+ ` customer-service/src/test/java/de/openknowledge/sample/address/domain/DeliveryAddressRepositoryTest.java ` :
36+
37+ 1 . ** ` getMax ` ** – Füge einen Response-Body hinzu, der die Lieferadresse von Max Mustermann beschreibt:
38+ - ` recipient ` : ` "Max Mustermann" `
39+ - ` city ` : ` "26122 Oldenburg" `
40+ - ` street.name ` : ` "Poststr." `
41+ - ` street.number ` : ` "1" `
42+
43+ 2 . ** ` dontGetMissing ` ** – Korrigiere den Statuscode: Eine nicht gefundene Adresse sollte ` 404 ` (nicht ` 204 ` ) zurückliefern.
44+
45+ 3 . ** ` updateMax ` ** – Füge einen Request-Body hinzu, der die neue Lieferadresse beschreibt:
46+ - ` recipient ` : ` "Erika Mustermann" `
47+ - ` city ` : ` "45127 Essen" `
48+ - ` street.name ` : ` "II. Hagen" `
49+ - ` street.number ` : ` "7" `
50+
51+ 4 . ** ` dontUpdateSherlock ` ** – Vervollständige Request und Response:
52+ - Füge einen ` Content-Type: application/json ` -Header-Match für den Request hinzu.
53+ - Füge einen Request-Body mit der Adresse von Sherlock Holmes hinzu:
54+ - ` recipient ` : ` "Sherlock Holmes" `
55+ - ` city ` : ` "London NW1 6XE" `
56+ - ` street.name ` : ` "Baker Street" `
57+ - ` street.number ` : ` "221B" `
58+ - Füge einen ` Content-Type: application/problem+json ` -Header-Match für die Response hinzu.
59+ - Füge einen Response-Body hinzu, der ein ` detail ` -Feld mit einer Fehlermeldung enthält
60+ (Matcher erlaubt beliebigen Text, Beispiel: ` "Addresses from UK are not supported for delivery" ` ).
61+
62+ Tipp: Verwende ` PactDslJsonBody ` (bereits als Abhängigkeit vorhanden) zum Aufbau der Bodies.
63+
64+ Wenn die Tests erfolgreich durchlaufen, werden die Pact-Dateien unter ` target/pacts/ ` erzeugt.
0 commit comments