Skip to content

Commit 553e2f6

Browse files
authored
Merge pull request #773 from xuzhenbao/remote_event_admin
Add event admin remote provider based on mqtt
2 parents db14807 + 295f71a commit 553e2f6

File tree

105 files changed

+12509
-109
lines changed

Some content is hidden

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

105 files changed

+12509
-109
lines changed

bundles/event_admin/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
celix_subproject(EVENT_ADMIN "Option to enable building the Event Admin bundles" ON)
1919
if (EVENT_ADMIN)
2020
add_subdirectory(event_admin_api)
21+
add_subdirectory(event_admin_spi)
2122
add_subdirectory(event_admin)
23+
add_subdirectory(remote_provider)
2224
add_subdirectory(examples)
2325
endif()
2426

bundles/event_admin/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,5 @@ If we want to build the event admin examples, the cmake option `BUILD_EVENT_ADMI
3939

4040
## Event Admin Bundles
4141

42-
* [EventAdmin](event_admin/README.md) - The event admin implementation.
42+
* [EventAdmin](event_admin/README.md) - The event admin implementation.
43+
* [RemoteProviders](remote_provider/README.md) - The remote providers implementation for the event admin. It is used to deliver events to remote frameworks. It is not a part of the OSGi Event Admin specification.

bundles/event_admin/event_admin/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ set(EVENT_ADMIN_SRC
2424

2525
set(EVENT_ADMIN_DEPS
2626
Celix::event_admin_api
27+
Celix::event_admin_spi
2728
Celix::log_helper
2829
Celix::framework
2930
Celix::utils

bundles/event_admin/event_admin/README.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@ event admin pubsub model, and events are delivered asynchronously.
3838

3939
### Properties/Configuration
4040

41-
| **Properties** | **Type** | **Description** | **Default value** |
42-
|----------------------------------------|----------|---------------------------------------------------------------|-----|
43-
| **CELIX_EVENT_ADMIN_HANDLER_THREADS** | long | The number of event handler threads. Its maximum value is 20. | 5 |
41+
| **Properties** | **Type** | **Description** | **Default value** |
42+
|----------------------------------------------------------|----------|---------------------------------------------------------------|-------------------|
43+
| **CELIX_EVENT_ADMIN_HANDLER_THREADS** | long | The number of event handler threads. Its maximum value is 20. | 5 |
44+
| **CELIX_EVENT_ADMIN_EVENT_SEQID_CACHE_CLEANUP_INTERVAL** | long | The event sequence id cache will be cleaned up when it has not been used for this interval. The unit is seconds. The event sequence id cache is used to prevent duplicate events. | (60*60)s |
4445

4546
### Software Design
4647

@@ -63,6 +64,17 @@ at most one event-delivery thread at a time, so that events can be delivered in
6364
"event.delivery" property to "async.unordered", the event handler can hold multiple event-delivery threads at the same
6465
time, so that events can be delivered in parallel.
6566

67+
#### Remote Event Delivery
68+
69+
If the event property "celix.event.remote.enable" is set to true, the event will be delivered to the local event handlers
70+
and remote event handlers. For delivering events to local event handlers, it can refer to the section of synchronous delivery
71+
and asynchronous delivery. For delivering events to remote event handlers, event admin will forward the event to the
72+
[remote provider](../remote_provider/README.md). The remote provider will serialize the event and send it to the remote framework.
73+
The remote framework will deserialize the event and deliver it to the remote event handler. The diagram of remote event delivery
74+
is as follows:
75+
76+
![remote_delivery_seq.png](diagrams/remote_event_delivery_seq.png)
77+
6678

6779
#### Event Adapter
6880

29.4 KB
Loading
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
Licensed to the Apache Software Foundation (ASF) under one or more
2+
contributor license agreements. See the NOTICE file distributed with
3+
this work for additional information regarding copyright ownership.
4+
The ASF licenses this file to You under the Apache License, Version 2.0
5+
(the "License"); you may not use this file except in compliance with
6+
the License. You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
16+
@startuml
17+
'https://plantuml.com/sequence-diagram
18+
19+
box FrameworkA
20+
participant "Event Admin" as EventAdmin1
21+
participant "Remote Provider" as RemoteProvider1
22+
end box
23+
24+
box FrameworkB
25+
participant "Remote Provider" as RemoteProvider2
26+
participant "Event Admin" as EventAdmin2
27+
end box
28+
29+
-\EventAdmin1:postEvent/sendEvent
30+
EventAdmin1->EventAdmin1:Delivery event to local event handlers
31+
alt "celix.event.remote.enable" is true
32+
EventAdmin1->EventAdmin1:Unset the "celix.event.remote.enable" property
33+
EventAdmin1->RemoteProvider1:postEvent/sendEvent
34+
RemoteProvider1->RemoteProvider2:IPC or Network
35+
RemoteProvider2->EventAdmin2:postEvent/sendEvent
36+
EventAdmin2 -> EventAdmin2:Delivery event to event handlers in FrameworkB
37+
end alt
38+
39+
@enduml

bundles/event_admin/event_admin/gtest/src/CelixEventAdminActivatorErrorInjectionTestSuite.cc

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,30 @@ TEST_F(CelixEventAdminActTestSuite, FailedToAddEventHandlerDependencyToEventAdmi
103103
});
104104
}
105105

106+
TEST_F(CelixEventAdminActTestSuite, FailedToCreateRemoteProviderDependencyForEventAdminTest) {
107+
TestEventAdminActivator([](void *act, celix_bundle_context_t *ctx) {
108+
celix_ei_expect_celix_dmServiceDependency_create((void*)&celix_bundleActivator_start, 1, nullptr, 2);
109+
auto status = celix_bundleActivator_start(act, ctx);
110+
ASSERT_EQ(CELIX_ENOMEM, status);
111+
});
112+
}
113+
114+
TEST_F(CelixEventAdminActTestSuite, FailedToSetServiceToRemoteProviderDependencyTest) {
115+
TestEventAdminActivator([](void *act, celix_bundle_context_t *ctx) {
116+
celix_ei_expect_celix_dmServiceDependency_setService((void*)&celix_bundleActivator_start, 1, CELIX_ENOMEM, 2);
117+
auto status = celix_bundleActivator_start(act, ctx);
118+
ASSERT_EQ(CELIX_ENOMEM, status);
119+
});
120+
}
121+
122+
TEST_F(CelixEventAdminActTestSuite, FailedToAddRemoteProviderDependencyToEventAdminComponentTest) {
123+
TestEventAdminActivator([](void *act, celix_bundle_context_t *ctx) {
124+
celix_ei_expect_celix_dmComponent_addServiceDependency((void*)&celix_bundleActivator_start, 1, CELIX_ENOMEM, 2);
125+
auto status = celix_bundleActivator_start(act, ctx);
126+
ASSERT_EQ(CELIX_ENOMEM, status);
127+
});
128+
}
129+
106130
TEST_F(CelixEventAdminActTestSuite, FailedToAddEventAdminServiceToComponentTest) {
107131
TestEventAdminActivator([](void *act, celix_bundle_context_t *ctx) {
108132
celix_ei_expect_celix_dmComponent_addInterface((void*)&celix_bundleActivator_start, 1, CELIX_ENOMEM);
@@ -129,23 +153,23 @@ TEST_F(CelixEventAdminActTestSuite, FailedToCreateEventAdapterTest) {
129153

130154
TEST_F(CelixEventAdminActTestSuite, FailedToCreateEventAdminDependencyForEventAdapterTest) {
131155
TestEventAdminActivator([](void *act, celix_bundle_context_t *ctx) {
132-
celix_ei_expect_celix_dmServiceDependency_create((void*)&celix_bundleActivator_start, 1, nullptr, 2);
156+
celix_ei_expect_celix_dmServiceDependency_create((void*)&celix_bundleActivator_start, 1, nullptr, 3);
133157
auto status = celix_bundleActivator_start(act, ctx);
134158
ASSERT_EQ(CELIX_ENOMEM, status);
135159
});
136160
}
137161

138162
TEST_F(CelixEventAdminActTestSuite, FailedToSetServiceToEventAdminDependencyTest) {
139163
TestEventAdminActivator([](void *act, celix_bundle_context_t *ctx) {
140-
celix_ei_expect_celix_dmServiceDependency_setService((void*)&celix_bundleActivator_start, 1, CELIX_ENOMEM, 2);
164+
celix_ei_expect_celix_dmServiceDependency_setService((void*)&celix_bundleActivator_start, 1, CELIX_ENOMEM, 3);
141165
auto status = celix_bundleActivator_start(act, ctx);
142166
ASSERT_EQ(CELIX_ENOMEM, status);
143167
});
144168
}
145169

146170
TEST_F(CelixEventAdminActTestSuite, FailedToAddEventAdminDependencyToEventAdapterComponentTest) {
147171
TestEventAdminActivator([](void *act, celix_bundle_context_t *ctx) {
148-
celix_ei_expect_celix_dmComponent_addServiceDependency((void*)&celix_bundleActivator_start, 1, CELIX_ENOMEM, 2);
172+
celix_ei_expect_celix_dmComponent_addServiceDependency((void*)&celix_bundleActivator_start, 1, CELIX_ENOMEM, 3);
149173
auto status = celix_bundleActivator_start(act, ctx);
150174
ASSERT_EQ(CELIX_ENOMEM, status);
151175
});

bundles/event_admin/event_admin/gtest/src/CelixEventAdminErrorInjectionTestSuite.cc

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
* specific language governing permissions and limitations
1717
* under the License.
1818
*/
19+
#include <cerrno>
20+
1921
#include "CelixEventAdminTestSuiteBaseClass.h"
2022
#include "celix_event_admin.h"
2123
#include "celix_event.h"
@@ -27,6 +29,8 @@
2729
#include "celix_long_hash_map_ei.h"
2830
#include "celix_threads_ei.h"
2931
#include "celix_utils_ei.h"
32+
#include "celix_properties_ei.h"
33+
#include "celix_bundle_context_ei.h"
3034
#include "malloc_ei.h"
3135
#include <gtest/gtest.h>
3236

@@ -51,6 +55,11 @@ class CelixEventAdminErrorInjectionTestSuite : public CelixEventAdminTestSuiteBa
5155
celix_ei_expect_celix_arrayList_addLong(nullptr, 0, 0);
5256
celix_ei_expect_celix_elapsedtime(nullptr, 0, 0);
5357
celix_ei_expect_celix_arrayList_createWithOptions(nullptr, 0, nullptr);
58+
celix_ei_expect_celix_properties_copy(nullptr, 0, nullptr);
59+
celix_ei_expect_celix_properties_set(nullptr, 0, 0);
60+
celix_ei_expect_celix_properties_setLong(nullptr, 0, 0);
61+
celix_ei_expect_celix_bundleContext_getProperty(nullptr, 0, nullptr);
62+
celix_ei_expect_celix_stringHashMap_createWithOptions(nullptr, 0, nullptr);
5463
}
5564
};
5665

@@ -89,6 +98,12 @@ TEST_F(CelixEventAdminErrorInjectionTestSuite, FailedToCreateLogHelperForEventAd
8998
EXPECT_EQ(nullptr, ea);
9099
}
91100

101+
TEST_F(CelixEventAdminErrorInjectionTestSuite, FailedToGetFrameworkUUIDForEventAdminTest) {
102+
celix_ei_expect_celix_bundleContext_getProperty((void*)&celix_eventAdmin_create, 0, nullptr);
103+
auto ea = celix_eventAdmin_create(ctx.get());
104+
EXPECT_EQ(nullptr, ea);
105+
}
106+
92107
TEST_F(CelixEventAdminErrorInjectionTestSuite, FailedToCreateLockForEventAdminTest) {
93108
celix_ei_expect_celixThreadRwlock_create((void*)&celix_eventAdmin_create, 0, CELIX_ENOMEM);
94109
auto ea = celix_eventAdmin_create(ctx.get());
@@ -119,6 +134,18 @@ TEST_F(CelixEventAdminErrorInjectionTestSuite, FailedToCreateEventHandlersMapFor
119134
EXPECT_EQ(nullptr, ea);
120135
}
121136

137+
TEST_F(CelixEventAdminErrorInjectionTestSuite, FailedToCreateEventSeqIdCacheForEventAdminTest) {
138+
celix_ei_expect_celix_stringHashMap_createWithOptions((void*)&celix_eventAdmin_create, 0, nullptr);
139+
auto ea = celix_eventAdmin_create(ctx.get());
140+
EXPECT_EQ(nullptr, ea);
141+
}
142+
143+
TEST_F(CelixEventAdminErrorInjectionTestSuite, FailedToCreateRemoteProviderMapForEventAdminTest) {
144+
celix_ei_expect_celix_longHashMap_create((void*)&celix_eventAdmin_create, 0, nullptr, 2);
145+
auto ea = celix_eventAdmin_create(ctx.get());
146+
EXPECT_EQ(nullptr, ea);
147+
}
148+
122149
TEST_F(CelixEventAdminErrorInjectionTestSuite, FailedToCreateMutexForEventAdminTest) {
123150
celix_ei_expect_celixThreadMutex_create((void*)&celix_eventAdmin_create, 0, CELIX_ENOMEM);
124151
auto ea = celix_eventAdmin_create(ctx.get());
@@ -339,4 +366,128 @@ TEST_F(CelixEventAdminErrorInjectionTestSuite, PostEventToBlacklistHandlerTest)
339366
EXPECT_STRNE("org/celix/test1", topic);
340367
return CELIX_SUCCESS;
341368
});
369+
}
370+
371+
TEST_F(CelixEventAdminErrorInjectionTestSuite, RetrieveEventSeqIdCacheTest) {
372+
int receivedEventCount = 0;
373+
TestPublishEvent("org/celix/test", nullptr, [](celix_event_admin_t *ea) {
374+
for (int i = 0; i < 32; i++) {
375+
celix_autoptr(celix_properties_t) eventProps = celix_properties_create();
376+
std::string uuid = "9748f803-5766-49f1-a2e9-" + std::to_string(i);
377+
celix_properties_set(eventProps, CELIX_EVENT_REMOTE_FRAMEWORK_UUID, uuid.c_str());
378+
celix_properties_setLong(eventProps, CELIX_EVENT_REMOTE_SEQ_ID, 1);
379+
auto status = celix_eventAdmin_sendEvent(ea, "org/celix/test", eventProps);
380+
EXPECT_EQ(CELIX_SUCCESS, status);
381+
}
382+
celix_ei_expect_celix_elapsedtime(CELIX_EI_UNKNOWN_CALLER, 0, 60*60+1);
383+
celix_autoptr(celix_properties_t) eventProps = celix_properties_create();
384+
celix_properties_set(eventProps, CELIX_EVENT_REMOTE_FRAMEWORK_UUID, "9748f803-5766-49f1-a2e9-9bbb522e874b");
385+
celix_properties_setLong(eventProps, CELIX_EVENT_REMOTE_SEQ_ID, 1);
386+
auto status = celix_eventAdmin_sendEvent(ea, "org/celix/test", eventProps);
387+
EXPECT_EQ(CELIX_SUCCESS, status);
388+
}, [&receivedEventCount](void*, const char*, const celix_properties_t*) {
389+
receivedEventCount ++;
390+
return CELIX_SUCCESS;
391+
});
392+
EXPECT_EQ(33, receivedEventCount);
393+
}
394+
395+
TEST_F(CelixEventAdminErrorInjectionTestSuite, FailedToCopyRemoteEnableEventPropertiesTest) {
396+
celix_event_remote_provider_service_t remoteProviderService;
397+
remoteProviderService.handle = nullptr;
398+
remoteProviderService.sendEvent = [](void*, const char*, const celix_properties_t*) {
399+
ADD_FAILURE() << "Should not be called";
400+
return CELIX_SUCCESS;
401+
};
402+
remoteProviderService.postEvent = [](void*, const char*, const celix_properties_t*) {
403+
ADD_FAILURE() << "Should not be called";
404+
return CELIX_SUCCESS;
405+
};
406+
TestPublishEventToRemote([](celix_event_admin_t *ea) {
407+
celix_ei_expect_celix_properties_copy((void*)&celix_eventAdmin_sendEvent, 1, nullptr);
408+
celix_autoptr(celix_properties_t) eventProps = celix_properties_create();
409+
celix_properties_setBool(eventProps, CELIX_EVENT_REMOTE_ENABLE, true);
410+
auto status = celix_eventAdmin_sendEvent(ea, "org/celix/test", eventProps);
411+
EXPECT_EQ(ENOMEM, status);
412+
}, &remoteProviderService);
413+
}
414+
415+
TEST_F(CelixEventAdminErrorInjectionTestSuite, FailedToSetRemoteFrameworkUUIDToRemoteEnableEventTest) {
416+
celix_event_remote_provider_service_t remoteProviderService;
417+
remoteProviderService.handle = nullptr;
418+
remoteProviderService.sendEvent = [](void*, const char*, const celix_properties_t*) {
419+
ADD_FAILURE() << "Should not be called";
420+
return CELIX_SUCCESS;
421+
};
422+
remoteProviderService.postEvent = [](void*, const char*, const celix_properties_t*) {
423+
ADD_FAILURE() << "Should not be called";
424+
return CELIX_SUCCESS;
425+
};
426+
TestPublishEventToRemote([](celix_event_admin_t *ea) {
427+
celix_ei_expect_celix_properties_set((void*)&celix_eventAdmin_sendEvent, 1, ENOMEM);
428+
celix_autoptr(celix_properties_t) eventProps = celix_properties_create();
429+
celix_properties_setBool(eventProps, CELIX_EVENT_REMOTE_ENABLE, true);
430+
auto status = celix_eventAdmin_sendEvent(ea, "org/celix/test", eventProps);
431+
EXPECT_EQ(ENOMEM, status);
432+
}, &remoteProviderService);
433+
}
434+
435+
TEST_F(CelixEventAdminErrorInjectionTestSuite, FailedToSetSeqIdToRemoteEnableEventTest) {
436+
celix_event_remote_provider_service_t remoteProviderService;
437+
remoteProviderService.handle = nullptr;
438+
remoteProviderService.sendEvent = [](void*, const char*, const celix_properties_t*) {
439+
ADD_FAILURE() << "Should not be called";
440+
return CELIX_SUCCESS;
441+
};
442+
remoteProviderService.postEvent = [](void*, const char*, const celix_properties_t*) {
443+
ADD_FAILURE() << "Should not be called";
444+
return CELIX_SUCCESS;
445+
};
446+
TestPublishEventToRemote([](celix_event_admin_t *ea) {
447+
celix_ei_expect_celix_properties_setLong((void*)&celix_eventAdmin_sendEvent, 1, ENOMEM);
448+
celix_autoptr(celix_properties_t) eventProps = celix_properties_create();
449+
celix_properties_setBool(eventProps, CELIX_EVENT_REMOTE_ENABLE, true);
450+
auto status = celix_eventAdmin_sendEvent(ea, "org/celix/test", eventProps);
451+
EXPECT_EQ(ENOMEM, status);
452+
}, &remoteProviderService);
453+
}
454+
455+
TEST_F(CelixEventAdminErrorInjectionTestSuite, FailedAllocMemoryForSeqIdCacheWhenSendRemoteEventTest) {
456+
int receivedEventCount = 0;
457+
TestPublishEvent("org/celix/test", nullptr, [](celix_event_admin_t *ea) {
458+
celix_ei_expect_calloc((void*)&celix_eventAdmin_sendEvent, 2, nullptr);
459+
celix_autoptr(celix_properties_t) eventProps = celix_properties_create();
460+
celix_properties_set(eventProps, CELIX_EVENT_REMOTE_FRAMEWORK_UUID, "9748f803-5766-49f1-a2e9-9bbb522e874a");
461+
celix_properties_setLong(eventProps, CELIX_EVENT_REMOTE_SEQ_ID, 1);
462+
auto status = celix_eventAdmin_sendEvent(ea, "org/celix/test", eventProps);
463+
EXPECT_EQ(CELIX_SUCCESS, status);
464+
465+
celix_properties_setLong(eventProps, CELIX_EVENT_REMOTE_SEQ_ID, 1);
466+
status = celix_eventAdmin_sendEvent(ea, "org/celix/test", eventProps);
467+
EXPECT_EQ(CELIX_SUCCESS, status);
468+
}, [&receivedEventCount](void*, const char*, const celix_properties_t*) {
469+
receivedEventCount ++;
470+
return CELIX_SUCCESS;
471+
});
472+
EXPECT_EQ(2, receivedEventCount);
473+
}
474+
475+
TEST_F(CelixEventAdminErrorInjectionTestSuite, FailedAddSeqIdCacheWhenSendRemoteEventTest) {
476+
int receivedEventCount = 0;
477+
TestPublishEvent("org/celix/test", nullptr, [](celix_event_admin_t *ea) {
478+
celix_ei_expect_celix_stringHashMap_put((void*)&celix_eventAdmin_sendEvent, 2, ENOMEM);
479+
celix_autoptr(celix_properties_t) eventProps = celix_properties_create();
480+
celix_properties_set(eventProps, CELIX_EVENT_REMOTE_FRAMEWORK_UUID, "9748f803-5766-49f1-a2e9-9bbb522e874a");
481+
celix_properties_setLong(eventProps, CELIX_EVENT_REMOTE_SEQ_ID, 1);
482+
auto status = celix_eventAdmin_sendEvent(ea, "org/celix/test", eventProps);
483+
EXPECT_EQ(CELIX_SUCCESS, status);
484+
485+
celix_properties_setLong(eventProps, CELIX_EVENT_REMOTE_SEQ_ID, 1);
486+
status = celix_eventAdmin_sendEvent(ea, "org/celix/test", eventProps);
487+
EXPECT_EQ(CELIX_SUCCESS, status);
488+
}, [&receivedEventCount](void*, const char*, const celix_properties_t*) {
489+
receivedEventCount ++;
490+
return CELIX_SUCCESS;
491+
});
492+
EXPECT_EQ(2, receivedEventCount);
342493
}

0 commit comments

Comments
 (0)