Skip to content

Commit 913099d

Browse files
committed
webhook: add test for https in test_webhook_delivery.py and fix the failure
1 parent 5790091 commit 913099d

File tree

2 files changed

+99
-6
lines changed

2 files changed

+99
-6
lines changed

plugins/event-bus/webhook/src/main/java/org/apache/cloudstack/mom/webhook/WebhookDeliveryThread.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ protected boolean isValidJson(String json) {
9696
}
9797

9898
protected void setHttpClient() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
99-
if (webhook.isSslVerification()) {
99+
if (!webhook.isSslVerification()) {
100100
httpClient = HttpClients.createDefault();
101101
return;
102102
}
@@ -160,11 +160,11 @@ public void setDeliveryTimeout(int deliveryTimeout) {
160160

161161
@Override
162162
public void run() {
163-
LOGGER.debug("Delivering event: {} for {}", event.getEventType(), webhook);
164163
if (event == null) {
165164
LOGGER.warn("Invalid event received for delivering to {}", webhook);
166165
return;
167166
}
167+
LOGGER.debug("Delivering event: {} for {}", event.getEventType(), webhook);
168168
payload = event.getDescription();
169169
LOGGER.trace("Payload: {}", payload);
170170
int attempt = 0;

test/integration/smoke/test_webhook_delivery.py

Lines changed: 97 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
""" BVT tests for webhooks delivery with a basic server
1818
"""
1919
# Import Local Modules
20+
from marvin.cloudstackAPI import issueCertificate
2021
from marvin.cloudstackTestCase import cloudstackTestCase
2122
from marvin.lib.base import (Account,
2223
Domain,
@@ -34,6 +35,8 @@
3435
import json
3536
import socket
3637
import _thread
38+
import tempfile
39+
import ssl
3740

3841

3942
_multiprocess_shared_ = True
@@ -55,15 +58,23 @@ def do_POST(self):
5558
event_id = self.headers.get('X-CS-Event-ID')
5659
print("POST request,\nPath: %s\nHeaders:\n%s\n\nBody:\n%s\n" %
5760
(str(self.path), str(self.headers), post_data))
58-
self._set_response()
5961
global deliveries_received
6062
if deliveries_received is None:
6163
deliveries_received = []
6264
deliveries_received.append({'event': event_id, 'payload': post_data})
65+
6366
if event_id != None:
64-
self.wfile.write("Event with ID: {} successfully processed!".format(str(event_id)).encode('utf-8'))
67+
data="Event with ID: {} successfully processed!".format(str(event_id)).encode('utf-8')
6568
else:
66-
self.wfile.write("POST request for {}".format(self.path).encode('utf-8'))
69+
data="POST request for {}".format(self.path).encode('utf-8')
70+
71+
self.send_response(200)
72+
self.send_header('Content-type', 'text/html')
73+
self.send_header('Content-Length', len(data))
74+
self.end_headers()
75+
76+
self.wfile.write(data)
77+
self.wfile.flush()
6778

6879
class TestWebhookDelivery(cloudstackTestCase):
6980

@@ -97,13 +108,38 @@ def setUpClass(cls):
97108
cls.webhook_receiver_url = "http://" + cls.server_ip + ":" + str(cls.server_port)
98109
cls.logger.debug("Running Webhook receiver @ %s" % cls.webhook_receiver_url)
99110
def startMgmtServer(tname, server):
100-
cls.logger.debug("Starting WebhookReceiver")
111+
cls.logger.debug("Starting WebhookReceiver %s" % tname)
101112
try:
102113
server.serve_forever()
103114
except Exception: pass
104115
cls.server = HTTPServer(('0.0.0.0', cls.server_port), WebhookReceiver)
105116
_thread.start_new_thread(startMgmtServer, ("webhook-receiver", cls.server,))
106117

118+
# Setup HTTPS server
119+
s = socket.socket()
120+
s.bind(('', 0))
121+
cls.server_port = s.getsockname()[1]
122+
s.close()
123+
cls.webhook_receiver_https_url = "https://" + cls.server_ip + ":" + str(cls.server_port)
124+
cls.logger.debug("Running Webhook HTTPS receiver @ %s" % cls.webhook_receiver_https_url)
125+
126+
cls.logger.debug("Getting certificate from management server")
127+
issueCertificateCmd = issueCertificate.issueCertificateCmd()
128+
issueCertificateCmd.domain = cls.server_ip
129+
issueCertificateResponse = cls.apiclient.issueCertificate(issueCertificateCmd)
130+
if issueCertificateResponse is None:
131+
cls.https_server = None
132+
else:
133+
with tempfile.NamedTemporaryFile(delete=False, mode="w") as cert_file, \
134+
tempfile.NamedTemporaryFile(delete=False, mode="w") as key_file:
135+
cert_file.write(issueCertificateResponse.certificate)
136+
key_file.write(issueCertificateResponse.privatekey)
137+
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
138+
ssl_context.load_cert_chain(certfile=cert_file.name, keyfile=key_file.name)
139+
cls.https_server = HTTPServer(('0.0.0.0', cls.server_port), WebhookReceiver)
140+
cls.https_server.socket = ssl_context.wrap_socket(cls.https_server.socket, server_side=True)
141+
_thread.start_new_thread(startMgmtServer, ("webhook-receiver-https", cls.https_server,))
142+
107143
cls._cleanup = []
108144

109145
@classmethod
@@ -122,6 +158,8 @@ def setUp(self):
122158
self.cleanup.append(self.domain1)
123159

124160
def tearDown(self):
161+
global deliveries_received
162+
deliveries_received = []
125163
super(TestWebhookDelivery, self).tearDown()
126164

127165
def popItemFromCleanup(self, item_id):
@@ -210,3 +248,58 @@ def test_01_webhook_deliveries(self):
210248
delivery_matched,
211249
"Delivery for %s did not match with server" % delivery.id
212250
)
251+
252+
@attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
253+
def test_02_webhook_deliveries_https(self):
254+
if not self.https_server:
255+
self.skipTest('Failed to setup HTTPS server. skipping')
256+
global deliveries_received
257+
self.createDomainAccount()
258+
self.createWebhook(self.userapiclient,
259+
payloadurl=self.webhook_receiver_https_url,
260+
sslverification=True)
261+
self.keypair = SSHKeyPair.register(
262+
self.userapiclient,
263+
name="Test-" + random_gen(),
264+
publickey="ssh-rsa: e6:9a:1e:b5:98:75:88:5d:56:bc:92:7b:43:48:05:b2"
265+
)
266+
self.logger.debug("Registered sshkeypair: %s" % str(self.keypair.__dict__))
267+
time.sleep(2)
268+
list_deliveries = self.webhook.list_deliveries(
269+
self.userapiclient,
270+
page=1,
271+
pagesize=20
272+
)
273+
self.assertNotEqual(
274+
list_deliveries,
275+
None,
276+
"Check webhook deliveries list"
277+
)
278+
self.assertTrue(
279+
len(list_deliveries) > 0,
280+
"Check webhook deliveries list length"
281+
)
282+
for delivery in list_deliveries:
283+
self.assertEqual(
284+
delivery.success,
285+
True,
286+
"Check webhook delivery success"
287+
)
288+
self.assertEqual(
289+
delivery.response,
290+
("Event with ID: %s successfully processed!" % delivery.eventid),
291+
"Check webhook delivery response"
292+
)
293+
delivery_matched = False
294+
for received in deliveries_received:
295+
if received['event'] == delivery.eventid:
296+
self.assertEqual(
297+
delivery.payload,
298+
received['payload'],
299+
"Check webhook delivery payload"
300+
)
301+
delivery_matched = True
302+
self.assertTrue(
303+
delivery_matched,
304+
"Delivery for %s did not match with server" % delivery.id
305+
)

0 commit comments

Comments
 (0)