Skip to content

Commit be552fd

Browse files
shwstpprDaanHooglandweizhouapache
authored
feature: webhooks (apache#8674)
* api,server,ui: weebhoks feature Signed-off-by: Abhishek Kumar <[email protected]> * fix Signed-off-by: Abhishek Kumar <[email protected]> * fix Signed-off-by: Abhishek Kumar <[email protected]> * changes Signed-off-by: Abhishek Kumar <[email protected]> * registry of message busses * test bus Signed-off-by: Abhishek Kumar <[email protected]> * refactor Signed-off-by: Abhishek Kumar <[email protected]> * test Signed-off-by: Abhishek Kumar <[email protected]> * fix and refactor Signed-off-by: Abhishek Kumar <[email protected]> * changes for webhook dispatch history Signed-off-by: Abhishek Kumar <[email protected]> * changes, initial ui Signed-off-by: Abhishek Kumar <[email protected]> * improvements Signed-off-by: Abhishek Kumar <[email protected]> * changes for account webhook cleanup Signed-off-by: Abhishek Kumar <[email protected]> * fix remaining event bus usage Signed-off-by: Abhishek Kumar <[email protected]> * changes for testing webhook dispatch Signed-off-by: Abhishek Kumar <[email protected]> * wip Signed-off-by: Abhishek Kumar <[email protected]> * fix test Signed-off-by: Abhishek Kumar <[email protected]> * make element Signed-off-by: Abhishek Kumar <[email protected]> * missing Signed-off-by: Abhishek Kumar <[email protected]> * buid fix * fix lint Signed-off-by: Abhishek Kumar <[email protected]> * changes for project delete check Signed-off-by: Abhishek Kumar <[email protected]> * fix Signed-off-by: Abhishek Kumar <[email protected]> * add collapse in create Signed-off-by: Abhishek Kumar <[email protected]> * ui fix and refactor for eventditributor publish Signed-off-by: Abhishek Kumar <[email protected]> * update org.json and add json validation Signed-off-by: Abhishek Kumar <[email protected]> * schema fixes Signed-off-by: Abhishek Kumar <[email protected]> * wordings Signed-off-by: Abhishek Kumar <[email protected]> * ui: improve progress button Signed-off-by: Abhishek Kumar <[email protected]> * ui improvements Signed-off-by: Abhishek Kumar <[email protected]> * remove unrelated change Signed-off-by: Abhishek Kumar <[email protected]> * search and count Signed-off-by: Abhishek Kumar <[email protected]> * add payloadurl in info Signed-off-by: Abhishek Kumar <[email protected]> * positive progress Signed-off-by: Abhishek Kumar <[email protected]> * fix hmac key Signed-off-by: Abhishek Kumar <[email protected]> * create webhook form fixes Signed-off-by: Abhishek Kumar <[email protected]> * refactor, address feedback Signed-off-by: Abhishek Kumar <[email protected]> * indentation Signed-off-by: Abhishek Kumar <[email protected]> * fix filters Signed-off-by: Abhishek Kumar <[email protected]> * remove test eventbus Signed-off-by: Abhishek Kumar <[email protected]> * default scope be Local Signed-off-by: Abhishek Kumar <[email protected]> * add lifecycle smoke test Signed-off-by: Abhishek Kumar <[email protected]> * add test for webhook deliveries Signed-off-by: Abhishek Kumar <[email protected]> * refactor Signed-off-by: Abhishek Kumar <[email protected]> * fix lint Signed-off-by: Abhishek Kumar <[email protected]> * refactor - losgs and others Signed-off-by: Abhishek Kumar <[email protected]> * unit tests Signed-off-by: Abhishek Kumar <[email protected]> * fix lint Signed-off-by: Abhishek Kumar <[email protected]> * build fix Signed-off-by: Abhishek Kumar <[email protected]> * smoke test fix, log refactor Signed-off-by: Abhishek Kumar <[email protected]> * get bean from all components Signed-off-by: Abhishek Kumar <[email protected]> * ui: missing label Signed-off-by: Abhishek Kumar <[email protected]> * address review comments Signed-off-by: Abhishek Kumar <[email protected]> * add some more tests Signed-off-by: Abhishek Kumar <[email protected]> * lint Signed-off-by: Abhishek Kumar <[email protected]> * rename setting Signed-off-by: Abhishek Kumar <[email protected]> * upgrade: move 4.19.0->4.20.0 to 4.19.1->4.20.0 * fix test delivery layout Signed-off-by: Abhishek Kumar <[email protected]> * fix webhook secret display Signed-off-by: Abhishek Kumar <[email protected]> * add http to payloadurl when no scheme Signed-off-by: Abhishek Kumar <[email protected]> * allow removing secretkey for webhook Signed-off-by: Abhishek Kumar <[email protected]> * fix update sslverification Signed-off-by: Abhishek Kumar <[email protected]> * disallow same payload url for same account Signed-off-by: Abhishek Kumar <[email protected]> * fix delivery with url w/o scheme Signed-off-by: Abhishek Kumar <[email protected]> * api: listApis should return params based on caller Signed-off-by: Abhishek Kumar <[email protected]> * wip changes Signed-off-by: Abhishek Kumar <[email protected]> * Update engine/schema/src/main/resources/META-INF/db/schema-41900to42000.sql * remove unique constraint for now Constraint is present in Java code validations Signed-off-by: Abhishek Kumar <[email protected]> * fixes Signed-off-by: Abhishek Kumar <[email protected]> * ui: add option to delete multiple deliveries Signed-off-by: Abhishek Kumar <[email protected]> * add filter for deliveries, delete api start/endtime support Signed-off-by: Abhishek Kumar <[email protected]> * do not throw error when no deliveries removed Signed-off-by: Abhishek Kumar <[email protected]> * ui: fix deliveries table column sorting, time filter cancel Signed-off-by: Abhishek Kumar <[email protected]> * remove isDebugEnabled wrapping * merge fix Signed-off-by: Abhishek Kumar <[email protected]> --------- Signed-off-by: Abhishek Kumar <[email protected]> Co-authored-by: Daan Hoogland <[email protected]> Co-authored-by: Wei Zhou <[email protected]>
1 parent 2542582 commit be552fd

File tree

102 files changed

+8734
-324
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+8734
-324
lines changed

.github/workflows/ci.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ jobs:
8686
smoke/test_migration
8787
smoke/test_multipleips_per_nic
8888
smoke/test_nested_virtualization
89-
smoke/test_set_sourcenat",
89+
smoke/test_set_sourcenat
90+
smoke/test_webhook_lifecycle",
9091
"smoke/test_network
9192
smoke/test_network_acl
9293
smoke/test_network_ipv6

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

+17-6
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ public class ApiConstants {
175175
public static final String END_IPV6 = "endipv6";
176176
public static final String END_PORT = "endport";
177177
public static final String ENTRY_TIME = "entrytime";
178+
public static final String EVENT_ID = "eventid";
179+
public static final String EVENT_TYPE = "eventtype";
178180
public static final String EXPIRES = "expires";
179181
public static final String EXTRA_CONFIG = "extraconfig";
180182
public static final String EXTRA_DHCP_OPTION = "extradhcpoption";
@@ -209,6 +211,7 @@ public class ApiConstants {
209211
public static final String HA_PROVIDER = "haprovider";
210212
public static final String HA_STATE = "hastate";
211213
public static final String HEALTH = "health";
214+
public static final String HEADERS = "headers";
212215
public static final String HIDE_IP_ADDRESS_USAGE = "hideipaddressusage";
213216
public static final String HOST_ID = "hostid";
214217
public static final String HOST_IDS = "hostids";
@@ -281,6 +284,7 @@ public class ApiConstants {
281284
public static final String JOB_STATUS = "jobstatus";
282285
public static final String KEEPALIVE_ENABLED = "keepaliveenabled";
283286
public static final String KERNEL_VERSION = "kernelversion";
287+
public static final String KEY = "key";
284288
public static final String LABEL = "label";
285289
public static final String LASTNAME = "lastname";
286290
public static final String LAST_BOOT = "lastboottime";
@@ -355,6 +359,7 @@ public class ApiConstants {
355359
public static final String SSHKEY_ENABLED = "sshkeyenabled";
356360
public static final String PATH = "path";
357361
public static final String PAYLOAD = "payload";
362+
public static final String PAYLOAD_URL = "payloadurl";
358363
public static final String POD_ID = "podid";
359364
public static final String POD_NAME = "podname";
360365
public static final String POD_IDS = "podids";
@@ -400,11 +405,9 @@ public class ApiConstants {
400405
public static final String QUERY_FILTER = "queryfilter";
401406
public static final String SCHEDULE = "schedule";
402407
public static final String SCOPE = "scope";
403-
public static final String SECRET_KEY = "usersecretkey";
404-
public static final String SECONDARY_IP = "secondaryip";
405-
public static final String SINCE = "since";
406-
public static final String KEY = "key";
407408
public static final String SEARCH_BASE = "searchbase";
409+
public static final String SECONDARY_IP = "secondaryip";
410+
public static final String SECRET_KEY = "secretkey";
408411
public static final String SECURITY_GROUP_IDS = "securitygroupids";
409412
public static final String SECURITY_GROUP_NAMES = "securitygroupnames";
410413
public static final String SECURITY_GROUP_NAME = "securitygroupname";
@@ -422,15 +425,15 @@ public class ApiConstants {
422425
public static final String SHOW_UNIQUE = "showunique";
423426
public static final String SIGNATURE = "signature";
424427
public static final String SIGNATURE_VERSION = "signatureversion";
428+
public static final String SINCE = "since";
425429
public static final String SIZE = "size";
426430
public static final String SNAPSHOT = "snapshot";
427431
public static final String SNAPSHOT_ID = "snapshotid";
428432
public static final String SNAPSHOT_POLICY_ID = "snapshotpolicyid";
429433
public static final String SNAPSHOT_TYPE = "snapshottype";
430434
public static final String SNAPSHOT_QUIESCEVM = "quiescevm";
431435
public static final String SOURCE_ZONE_ID = "sourcezoneid";
432-
public static final String SUITABLE_FOR_VM = "suitableforvirtualmachine";
433-
public static final String SUPPORTS_STORAGE_SNAPSHOT = "supportsstoragesnapshot";
436+
public static final String SSL_VERIFICATION = "sslverification";
434437
public static final String START_DATE = "startdate";
435438
public static final String START_ID = "startid";
436439
public static final String START_IP = "startip";
@@ -449,6 +452,9 @@ public class ApiConstants {
449452
public static final String SYSTEM_VM_TYPE = "systemvmtype";
450453
public static final String TAGS = "tags";
451454
public static final String STORAGE_TAGS = "storagetags";
455+
public static final String SUCCESS = "success";
456+
public static final String SUITABLE_FOR_VM = "suitableforvirtualmachine";
457+
public static final String SUPPORTS_STORAGE_SNAPSHOT = "supportsstoragesnapshot";
452458
public static final String TARGET_IQN = "targetiqn";
453459
public static final String TEMPLATE_FILTER = "templatefilter";
454460
public static final String TEMPLATE_ID = "templateid";
@@ -482,6 +488,7 @@ public class ApiConstants {
482488
public static final String USERNAME = "username";
483489
public static final String USER_CONFIGURABLE = "userconfigurable";
484490
public static final String USER_SECURITY_GROUP_LIST = "usersecuritygrouplist";
491+
public static final String USER_SECRET_KEY = "usersecretkey";
485492
public static final String USE_VIRTUAL_NETWORK = "usevirtualnetwork";
486493
public static final String UPDATE_IN_SEQUENCE = "updateinsequence";
487494
public static final String VALUE = "value";
@@ -561,6 +568,7 @@ public class ApiConstants {
561568
public static final String ALLOCATION_STATE = "allocationstate";
562569
public static final String MANAGED_STATE = "managedstate";
563570
public static final String MANAGEMENT_SERVER_ID = "managementserverid";
571+
public static final String MANAGEMENT_SERVER_NAME = "managementservername";
564572
public static final String STORAGE = "storage";
565573
public static final String STORAGE_ID = "storageid";
566574
public static final String PING_STORAGE_SERVER_IP = "pingstorageserverip";
@@ -1121,6 +1129,9 @@ public class ApiConstants {
11211129

11221130
public static final String PARAMETER_DESCRIPTION_IS_TAG_A_RULE = "Whether the informed tag is a JS interpretable rule or not.";
11231131

1132+
public static final String WEBHOOK_ID = "webhookid";
1133+
public static final String WEBHOOK_NAME = "webhookname";
1134+
11241135
/**
11251136
* This enum specifies IO Drivers, each option controls specific policies on I/O.
11261137
* Qemu guests support "threads" and "native" options Since 0.8.8 ; "io_uring" is supported Since 6.3.0 (QEMU 5.0).

api/src/main/java/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public class UpdateUserCmd extends BaseCmd {
6666
@Parameter(name = ApiConstants.CURRENT_PASSWORD, type = CommandType.STRING, description = "Current password that was being used by the user. You must inform the current password when updating the password.", acceptedOnAdminPort = false)
6767
private String currentPassword;
6868

69-
@Parameter(name = ApiConstants.SECRET_KEY, type = CommandType.STRING, description = "The secret key for the user. Must be specified with userApiKey")
69+
@Parameter(name = ApiConstants.USER_SECRET_KEY, type = CommandType.STRING, description = "The secret key for the user. Must be specified with userApiKey")
7070
private String secretKey;
7171

7272
@Parameter(name = ApiConstants.TIMEZONE,

api/src/main/java/org/apache/cloudstack/api/response/BucketResponse.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public class BucketResponse extends BaseResponseWithTagInformation implements Co
9898
@Param(description = "Bucket Access Key")
9999
private String accessKey;
100100

101-
@SerializedName(ApiConstants.SECRET_KEY)
101+
@SerializedName(ApiConstants.USER_SECRET_KEY)
102102
@Param(description = "Bucket Secret Key")
103103
private String secretKey;
104104

client/pom.xml

+5
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,11 @@
438438
<artifactId>cloud-mom-kafka</artifactId>
439439
<version>${project.version}</version>
440440
</dependency>
441+
<dependency>
442+
<groupId>org.apache.cloudstack</groupId>
443+
<artifactId>cloud-mom-webhook</artifactId>
444+
<version>${project.version}</version>
445+
</dependency>
441446
<dependency>
442447
<groupId>org.apache.cloudstack</groupId>
443448
<artifactId>cloud-framework-agent-lb</artifactId>

core/src/main/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml

+7-2
Original file line numberDiff line numberDiff line change
@@ -288,10 +288,10 @@
288288
</bean>
289289

290290
<bean id="hypervisorGurusRegistry"
291-
class="org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry">
291+
class="org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry">
292292
<property name="excludeKey" value="hypervisor.gurus.exclude" />
293293
</bean>
294-
294+
295295
<bean id="vpcProvidersRegistry"
296296
class="org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry">
297297
<property name="excludeKey" value="vpc.providers.exclude" />
@@ -358,4 +358,9 @@
358358
</list>
359359
</property>
360360
</bean>
361+
362+
<bean id="eventBusRegistry"
363+
class="org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry">
364+
<property name="excludeKey" value="event.buses.exclude" />
365+
</bean>
361366
</beans>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one
3+
# or more contributor license agreements. See the NOTICE file
4+
# distributed with this work for additional information
5+
# regarding copyright ownership. The ASF licenses this file
6+
# to you under the Apache License, Version 2.0 (the
7+
# "License"); you may not use this file except in compliance
8+
# with the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing,
13+
# software distributed under the License is distributed on an
14+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
# KIND, either express or implied. See the License for the
16+
# specific language governing permissions and limitations
17+
# under the License.
18+
#
19+
20+
name=event
21+
parent=core
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<!--
2+
3+
Licensed to the Apache Software Foundation (ASF) under one
4+
or more contributor license agreements. See the NOTICE file
5+
distributed with this work for additional information
6+
regarding copyright ownership. The ASF licenses this file
7+
to you under the Apache License, Version 2.0 (the
8+
"License"); you may not use this file except in compliance
9+
with the License. You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing,
14+
software distributed under the License is distributed on an
15+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
KIND, either express or implied. See the License for the
17+
specific language governing permissions and limitations
18+
under the License.
19+
20+
-->
21+
<beans xmlns="http://www.springframework.org/schema/beans"
22+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
23+
xsi:schemaLocation="http://www.springframework.org/schema/beans
24+
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
25+
>
26+
<bean class="org.apache.cloudstack.spring.lifecycle.registry.RegistryLifecycle">
27+
<property name="registry" ref="eventBusRegistry" />
28+
<property name="typeClass" value="org.apache.cloudstack.framework.events.EventBus" />
29+
</bean>
30+
31+
</beans>

engine/components-api/src/main/java/com/cloud/event/UsageEventUtils.java

+9-13
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,14 @@
2525
import javax.annotation.PostConstruct;
2626
import javax.inject.Inject;
2727

28-
import org.apache.commons.collections.MapUtils;
29-
import org.apache.logging.log4j.Logger;
30-
import org.apache.logging.log4j.LogManager;
31-
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
32-
3328
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
3429
import org.apache.cloudstack.framework.events.Event;
3530
import org.apache.cloudstack.framework.events.EventBus;
36-
import org.apache.cloudstack.framework.events.EventBusException;
31+
import org.apache.cloudstack.framework.events.EventDistributor;
32+
import org.apache.commons.collections.MapUtils;
33+
import org.apache.logging.log4j.LogManager;
34+
import org.apache.logging.log4j.Logger;
35+
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
3736

3837
import com.cloud.dc.DataCenterVO;
3938
import com.cloud.dc.dao.DataCenterDao;
@@ -50,6 +49,7 @@ public class UsageEventUtils {
5049
protected static Logger LOGGER = LogManager.getLogger(UsageEventUtils.class);
5150
protected static EventBus s_eventBus = null;
5251
protected static ConfigurationDao s_configDao;
52+
private static EventDistributor eventDistributor;
5353

5454
@Inject
5555
UsageEventDao usageEventDao;
@@ -207,9 +207,9 @@ private static void publishUsageEvent(String usageEventType, Long accountId, Lon
207207
if( !configValue)
208208
return;
209209
try {
210-
s_eventBus = ComponentContext.getComponent(EventBus.class);
210+
eventDistributor = ComponentContext.getComponent(EventDistributor.class);
211211
} catch (NoSuchBeanDefinitionException nbe) {
212-
return; // no provider is configured to provide events bus, so just return
212+
return; // no provider is configured to provide events distributor, so just return
213213
}
214214

215215
Account account = s_accountDao.findById(accountId);
@@ -238,11 +238,7 @@ private static void publishUsageEvent(String usageEventType, Long accountId, Lon
238238

239239
event.setDescription(eventDescription);
240240

241-
try {
242-
s_eventBus.publish(event);
243-
} catch (EventBusException e) {
244-
LOGGER.warn("Failed to publish usage event on the event bus.");
245-
}
241+
eventDistributor.publish(event);
246242
}
247243

248244
static final String Name = "management-server";

engine/components-api/src/main/java/com/cloud/network/NetworkStateListener.java

+14-18
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,9 @@
2525
import javax.inject.Inject;
2626

2727
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
28-
import org.apache.cloudstack.framework.events.EventBus;
29-
import org.apache.cloudstack.framework.events.EventBusException;
30-
import org.apache.logging.log4j.Logger;
28+
import org.apache.cloudstack.framework.events.EventDistributor;
3129
import org.apache.logging.log4j.LogManager;
32-
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
30+
import org.apache.logging.log4j.Logger;
3331

3432
import com.cloud.event.EventCategory;
3533
import com.cloud.network.Network.Event;
@@ -43,14 +41,18 @@ public class NetworkStateListener implements StateListener<State, Event, Network
4341
@Inject
4442
private ConfigurationDao _configDao;
4543

46-
private static EventBus s_eventBus = null;
44+
private EventDistributor eventDistributor;
4745

4846
protected Logger logger = LogManager.getLogger(getClass());
4947

5048
public NetworkStateListener(ConfigurationDao configDao) {
5149
_configDao = configDao;
5250
}
5351

52+
public void setEventDistributor(EventDistributor eventDistributor) {
53+
this.eventDistributor = eventDistributor;
54+
}
55+
5456
@Override
5557
public boolean preStateTransitionEvent(State oldState, Event event, State newState, Network vo, boolean status, Object opaque) {
5658
pubishOnEventBus(event.name(), "preStateTransitionEvent", vo, oldState, newState);
@@ -66,23 +68,20 @@ public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> t
6668
return true;
6769
}
6870

69-
private void pubishOnEventBus(String event, String status, Network vo, State oldState, State newState) {
70-
71+
private void pubishOnEventBus(String event, String status, Network vo, State oldState, State newState) {
7172
String configKey = "publish.resource.state.events";
7273
String value = _configDao.getValue(configKey);
7374
boolean configValue = Boolean.parseBoolean(value);
7475
if(!configValue)
7576
return;
76-
try {
77-
s_eventBus = ComponentContext.getComponent(EventBus.class);
78-
} catch (NoSuchBeanDefinitionException nbe) {
79-
return; // no provider is configured to provide events bus, so just return
77+
if (eventDistributor == null) {
78+
setEventDistributor(ComponentContext.getComponent(EventDistributor.class));
8079
}
8180

8281
String resourceName = getEntityFromClassName(Network.class.getName());
8382
org.apache.cloudstack.framework.events.Event eventMsg =
84-
new org.apache.cloudstack.framework.events.Event("management-server", EventCategory.RESOURCE_STATE_CHANGE_EVENT.getName(), event, resourceName, vo.getUuid());
85-
Map<String, String> eventDescription = new HashMap<String, String>();
83+
new org.apache.cloudstack.framework.events.Event("management-server", EventCategory.RESOURCE_STATE_CHANGE_EVENT.getName(), event, resourceName, vo.getUuid());
84+
Map<String, String> eventDescription = new HashMap<>();
8685
eventDescription.put("resource", resourceName);
8786
eventDescription.put("id", vo.getUuid());
8887
eventDescription.put("old-state", oldState.name());
@@ -92,11 +91,8 @@ private void pubishOnEventBus(String event, String status, Network vo, State old
9291
eventDescription.put("eventDateTime", eventDate);
9392

9493
eventMsg.setDescription(eventDescription);
95-
try {
96-
s_eventBus.publish(eventMsg);
97-
} catch (EventBusException e) {
98-
logger.warn("Failed to publish state change event on the event bus.");
99-
}
94+
95+
eventDistributor.publish(eventMsg);
10096
}
10197

10298
private String getEntityFromClassName(String entityClassName) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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+
package com.cloud.network;
18+
19+
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
20+
import org.apache.cloudstack.framework.events.EventDistributor;
21+
import org.junit.Assert;
22+
import org.junit.Test;
23+
import org.mockito.InjectMocks;
24+
import org.mockito.Mockito;
25+
import org.springframework.test.util.ReflectionTestUtils;
26+
27+
public class NetworkStateListenerTest {
28+
@InjectMocks
29+
NetworkStateListener networkStateListener = new NetworkStateListener(Mockito.mock(ConfigurationDao.class));
30+
31+
@Test
32+
public void testSetEventDistributor() {
33+
EventDistributor eventDistributor = null;
34+
networkStateListener.setEventDistributor(eventDistributor);
35+
Assert.assertNull(ReflectionTestUtils.getField(networkStateListener, "eventDistributor"));
36+
eventDistributor = Mockito.mock(EventDistributor.class);
37+
networkStateListener.setEventDistributor(eventDistributor);
38+
Assert.assertEquals(eventDistributor, ReflectionTestUtils.getField(networkStateListener, "eventDistributor"));
39+
}
40+
}

0 commit comments

Comments
 (0)