Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ public class ApiConstants {
public static final String MAC_ADDRESS = "macaddress";
public static final String MAC_ADDRESSES = "macaddresses";
public static final String MANUAL_UPGRADE = "manualupgrade";
public static final String MATCH_TYPE = "matchtype";
public static final String MAX = "max";
public static final String MAX_SNAPS = "maxsnaps";
public static final String MAX_BACKUPS = "maxbackups";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,19 @@
--;
-- Schema upgrade from 4.22.0.0 to 4.23.0.0
--;

-- Create webhook_filter table
DROP TABLE IF EXISTS `cloud`.`webhook_filter`;
CREATE TABLE IF NOT EXISTS `cloud`.`webhook_filter` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id of the webhook filter',
`uuid` varchar(255) COMMENT 'uuid of the webhook filter',
`webhook_id` bigint unsigned NOT NULL COMMENT 'id of the webhook',
`type` varchar(20) COMMENT 'type of the filter',
`mode` varchar(20) COMMENT 'mode of the filter',
`match_type` varchar(20) COMMENT 'match type of the filter',
`value` varchar(256) NOT NULL COMMENT 'value of the filter used for matching',
`created` datetime NOT NULL COMMENT 'date created',
PRIMARY KEY (`id`),
INDEX `i_webhook_filter__webhook_id`(`webhook_id`),
CONSTRAINT `fk_webhook_filter__webhook_id` FOREIGN KEY(`webhook_id`) REFERENCES `webhook`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
import org.apache.cloudstack.api.InternalIdentity;

public interface Webhook extends ControlledEntity, Identity, InternalIdentity {
public static final long ID_DUMMY = 0L;
public static final String NAME_DUMMY = "Test";
long ID_DUMMY = 0L;
String NAME_DUMMY = "Test";
enum State {
Enabled, Disabled;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,18 @@
package org.apache.cloudstack.mom.webhook;

import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.mom.webhook.api.command.user.AddWebhookFilterCmd;
import org.apache.cloudstack.mom.webhook.api.command.user.CreateWebhookCmd;
import org.apache.cloudstack.mom.webhook.api.command.user.DeleteWebhookCmd;
import org.apache.cloudstack.mom.webhook.api.command.user.DeleteWebhookDeliveryCmd;
import org.apache.cloudstack.mom.webhook.api.command.user.DeleteWebhookFilterCmd;
import org.apache.cloudstack.mom.webhook.api.command.user.ExecuteWebhookDeliveryCmd;
import org.apache.cloudstack.mom.webhook.api.command.user.ListWebhookDeliveriesCmd;
import org.apache.cloudstack.mom.webhook.api.command.user.ListWebhookFiltersCmd;
import org.apache.cloudstack.mom.webhook.api.command.user.ListWebhooksCmd;
import org.apache.cloudstack.mom.webhook.api.command.user.UpdateWebhookCmd;
import org.apache.cloudstack.mom.webhook.api.response.WebhookDeliveryResponse;
import org.apache.cloudstack.mom.webhook.api.response.WebhookFilterResponse;
import org.apache.cloudstack.mom.webhook.api.response.WebhookResponse;

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

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package org.apache.cloudstack.mom.webhook;

import java.util.Date;
import java.util.List;

import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;

public interface WebhookFilter extends Identity, InternalIdentity {

enum Type {
EventType
}

enum Mode {
Include, Exclude
}

enum MatchType {
Exact, Prefix, Suffix, Contains
}

long getId();
long getWebhookId();
Type getType();
Mode getMode();
MatchType getMatchType();
String getValue();
Date getCreated();

static boolean overlaps(WebhookFilter.MatchType oldMatchType, String oldValue, WebhookFilter.MatchType newMatchType, String newValue) {
switch (oldMatchType) {
case Exact:
switch (newMatchType) {
case Exact:
return oldValue.equals(newValue);
}
break;

case Prefix:
switch (newMatchType) {
case Exact:
case Prefix:
return newValue.startsWith(oldValue);
}
break;

case Suffix:
switch (newMatchType) {
case Exact:
case Suffix:
return newValue.endsWith(oldValue);
}
break;

case Contains:
switch (newMatchType) {
case Exact:
case Prefix:
case Suffix:
case Contains:
return newValue.contains(oldValue);
}
break;

default:
break;
}
return false;
}

default WebhookFilter getConflicting(List<? extends WebhookFilter> existing) {
for (WebhookFilter f : existing) {
if (f.getType() != this.getType()) {
continue;
}

// 1. Duplicate entry (same mode, match type, and value)
if (f.getMode() == this.getMode()
&& f.getMatchType() == this.getMatchType()
&& f.getValue().equalsIgnoreCase(this.getValue())) {
return f;
}

// 2. Opposite mode (INCLUDE vs EXCLUDE) — check for overlap
if (Mode.Exclude.equals(f.getMode())
&& Mode.Include.equals(this.getMode())) {
String oldVal = f.getValue().toUpperCase();
String newVal = this.getValue().toUpperCase();

if (overlaps(f.getMatchType(), oldVal, this.getMatchType(), newVal)) {
return f;
}
}
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,6 @@ public interface WebhookService extends PluggableService, Configurable {
void handleEvent(Event event) throws EventBusException;
WebhookDelivery executeWebhookDelivery(WebhookDelivery delivery, Webhook webhook, String payload)
throws CloudRuntimeException;
void invalidateWebhooksCache();
void invalidateWebhookFiltersCache(long webhookId);
}
Loading
Loading