Skip to content

Commit cd55796

Browse files
authored
webhook: fixes, filter enhancement (#12023)
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
1 parent 81b991a commit cd55796

38 files changed

+4302
-122
lines changed

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ public class ApiConstants {
375375
public static final String MAC_ADDRESS = "macaddress";
376376
public static final String MAC_ADDRESSES = "macaddresses";
377377
public static final String MANUAL_UPGRADE = "manualupgrade";
378+
public static final String MATCH_TYPE = "matchtype";
378379
public static final String MAX = "max";
379380
public static final String MAX_SNAPS = "maxsnaps";
380381
public static final String MAX_BACKUPS = "maxbackups";

engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,19 @@
2323
-- Update value to firstfit for the config 'vm.allocation.algorithm' or 'volume.allocation.algorithm' if configured as userconcentratedpod_firstfit
2424
UPDATE `cloud`.`configuration` SET value='random' WHERE name IN ('vm.allocation.algorithm', 'volume.allocation.algorithm') AND value='userconcentratedpod_random';
2525
UPDATE `cloud`.`configuration` SET value='firstfit' WHERE name IN ('vm.allocation.algorithm', 'volume.allocation.algorithm') AND value='userconcentratedpod_firstfit';
26+
27+
-- Create webhook_filter table
28+
DROP TABLE IF EXISTS `cloud`.`webhook_filter`;
29+
CREATE TABLE IF NOT EXISTS `cloud`.`webhook_filter` (
30+
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id of the webhook filter',
31+
`uuid` varchar(255) COMMENT 'uuid of the webhook filter',
32+
`webhook_id` bigint unsigned NOT NULL COMMENT 'id of the webhook',
33+
`type` varchar(20) COMMENT 'type of the filter',
34+
`mode` varchar(20) COMMENT 'mode of the filter',
35+
`match_type` varchar(20) COMMENT 'match type of the filter',
36+
`value` varchar(256) NOT NULL COMMENT 'value of the filter used for matching',
37+
`created` datetime NOT NULL COMMENT 'date created',
38+
PRIMARY KEY (`id`),
39+
INDEX `i_webhook_filter__webhook_id`(`webhook_id`),
40+
CONSTRAINT `fk_webhook_filter__webhook_id` FOREIGN KEY(`webhook_id`) REFERENCES `webhook`(`id`) ON DELETE CASCADE
41+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
import org.apache.cloudstack.api.InternalIdentity;
2525

2626
public interface Webhook extends ControlledEntity, Identity, InternalIdentity {
27-
public static final long ID_DUMMY = 0L;
28-
public static final String NAME_DUMMY = "Test";
27+
long ID_DUMMY = 0L;
28+
String NAME_DUMMY = "Test";
2929
enum State {
3030
Enabled, Disabled;
3131
};

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,18 @@
1818
package org.apache.cloudstack.mom.webhook;
1919

2020
import org.apache.cloudstack.api.response.ListResponse;
21+
import org.apache.cloudstack.mom.webhook.api.command.user.AddWebhookFilterCmd;
2122
import org.apache.cloudstack.mom.webhook.api.command.user.CreateWebhookCmd;
2223
import org.apache.cloudstack.mom.webhook.api.command.user.DeleteWebhookCmd;
2324
import org.apache.cloudstack.mom.webhook.api.command.user.DeleteWebhookDeliveryCmd;
25+
import org.apache.cloudstack.mom.webhook.api.command.user.DeleteWebhookFilterCmd;
2426
import org.apache.cloudstack.mom.webhook.api.command.user.ExecuteWebhookDeliveryCmd;
2527
import org.apache.cloudstack.mom.webhook.api.command.user.ListWebhookDeliveriesCmd;
28+
import org.apache.cloudstack.mom.webhook.api.command.user.ListWebhookFiltersCmd;
2629
import org.apache.cloudstack.mom.webhook.api.command.user.ListWebhooksCmd;
2730
import org.apache.cloudstack.mom.webhook.api.command.user.UpdateWebhookCmd;
2831
import org.apache.cloudstack.mom.webhook.api.response.WebhookDeliveryResponse;
32+
import org.apache.cloudstack.mom.webhook.api.response.WebhookFilterResponse;
2933
import org.apache.cloudstack.mom.webhook.api.response.WebhookResponse;
3034

3135
import com.cloud.utils.component.PluggableService;
@@ -41,4 +45,7 @@ public interface WebhookApiService extends PluggableService {
4145
ListResponse<WebhookDeliveryResponse> listWebhookDeliveries(ListWebhookDeliveriesCmd cmd);
4246
int deleteWebhookDelivery(DeleteWebhookDeliveryCmd cmd) throws CloudRuntimeException;
4347
WebhookDeliveryResponse executeWebhookDelivery(ExecuteWebhookDeliveryCmd cmd) throws CloudRuntimeException;
48+
ListResponse<WebhookFilterResponse> listWebhookFilters(ListWebhookFiltersCmd cmd) throws CloudRuntimeException;
49+
WebhookFilterResponse addWebhookFilter(AddWebhookFilterCmd cmd) throws CloudRuntimeException;
50+
int deleteWebhookFilter(DeleteWebhookFilterCmd cmd) throws CloudRuntimeException;
4451
}

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

Lines changed: 170 additions & 52 deletions
Large diffs are not rendered by default.
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.apache.cloudstack.mom.webhook;
19+
20+
import java.util.Date;
21+
import java.util.List;
22+
23+
import org.apache.cloudstack.api.Identity;
24+
import org.apache.cloudstack.api.InternalIdentity;
25+
26+
public interface WebhookFilter extends Identity, InternalIdentity {
27+
28+
enum Type {
29+
EventType
30+
}
31+
32+
enum Mode {
33+
Include, Exclude
34+
}
35+
36+
enum MatchType {
37+
Exact, Prefix, Suffix, Contains
38+
}
39+
40+
long getId();
41+
long getWebhookId();
42+
Type getType();
43+
Mode getMode();
44+
MatchType getMatchType();
45+
String getValue();
46+
Date getCreated();
47+
48+
static boolean overlaps(WebhookFilter.MatchType oldMatchType, String oldValue, WebhookFilter.MatchType newMatchType, String newValue) {
49+
switch (oldMatchType) {
50+
case Exact:
51+
switch (newMatchType) {
52+
case Exact:
53+
return oldValue.equals(newValue);
54+
}
55+
break;
56+
57+
case Prefix:
58+
switch (newMatchType) {
59+
case Exact:
60+
case Prefix:
61+
return newValue.startsWith(oldValue);
62+
}
63+
break;
64+
65+
case Suffix:
66+
switch (newMatchType) {
67+
case Exact:
68+
case Suffix:
69+
return newValue.endsWith(oldValue);
70+
}
71+
break;
72+
73+
case Contains:
74+
switch (newMatchType) {
75+
case Exact:
76+
case Prefix:
77+
case Suffix:
78+
case Contains:
79+
return newValue.contains(oldValue);
80+
}
81+
break;
82+
83+
default:
84+
break;
85+
}
86+
return false;
87+
}
88+
89+
default WebhookFilter getConflicting(List<? extends WebhookFilter> existing) {
90+
for (WebhookFilter f : existing) {
91+
if (f.getType() != this.getType()) {
92+
continue;
93+
}
94+
95+
// 1. Duplicate entry (same mode, match type, and value)
96+
if (f.getMode() == this.getMode()
97+
&& f.getMatchType() == this.getMatchType()
98+
&& f.getValue().equalsIgnoreCase(this.getValue())) {
99+
return f;
100+
}
101+
102+
// 2. Opposite mode (INCLUDE vs EXCLUDE) — check for overlap
103+
if (f.getMode() != this.getMode()) {
104+
String oldVal = f.getValue().toUpperCase();
105+
String newVal = this.getValue().toUpperCase();
106+
107+
if (overlaps(f.getMatchType(), oldVal, this.getMatchType(), newVal)) {
108+
return f;
109+
}
110+
}
111+
}
112+
return null;
113+
}
114+
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,6 @@ public interface WebhookService extends PluggableService, Configurable {
6060
void handleEvent(Event event) throws EventBusException;
6161
WebhookDelivery executeWebhookDelivery(WebhookDelivery delivery, Webhook webhook, String payload)
6262
throws CloudRuntimeException;
63+
void invalidateWebhooksCache();
64+
void invalidateWebhookFiltersCache(long webhookId);
6365
}

0 commit comments

Comments
 (0)