Skip to content

Commit 2d66a54

Browse files
RobertLauferElektrobittcormackMWToby Cormack
authored
Allow for global namespacing in interface definitions and manifests (CppMicroServices#1048) (CppMicroServices#1158)
* first commit figuring out what DOESN'T work * tests passing * remove superfluous cout * update to ensure no segfault * create a bundle exclusively for fragile test * no need for new bundle * compartmentalize tests * remove superfluous test --------- Co-authored-by: tcormackMW <113473781+tcormackMW@users.noreply.github.com> Co-authored-by: Toby Cormack <tcormack@vdi-ah2ddp-086.dhcp.mathworks.com>
1 parent 9610f1f commit 2d66a54

6 files changed

Lines changed: 93 additions & 13 deletions

File tree

compendium/DeclarativeServices/src/metadata/MetadataParserImpl.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ namespace cppmicroservices
3838
namespace metadata
3939
{
4040

41+
std::string
42+
removeLeadingNamespacing(std::string const& className)
43+
{
44+
auto ind = className.find_first_not_of(':');
45+
if (ind == std::string::npos)
46+
{
47+
return className;
48+
}
49+
return className.substr(ind);
50+
}
51+
4152
ServiceMetadata
4253
MetadataParserImplV1::CreateServiceMetadata(AnyMap const& metadata) const
4354
{
@@ -49,8 +60,9 @@ namespace cppmicroservices
4960
std::transform(std::begin(interfaces),
5061
std::end(interfaces),
5162
std::back_inserter(serviceMetadata.interfaces),
52-
[](auto const& interface)
53-
{ return ObjectValidator(interface).GetValue<std::string>(); });
63+
[](auto const& interface) {
64+
return removeLeadingNamespacing(ObjectValidator(interface).GetValue<std::string>());
65+
});
5466

5567
// service.scope
5668
auto const object = ObjectValidator(metadata, "scope", /*isOptional=*/true);
@@ -67,7 +79,7 @@ namespace cppmicroservices
6779

6880
// reference.interface (Mandatory)
6981
ObjectValidator(metadata, "interface").AssignValueTo(refMetadata.interfaceName);
70-
82+
refMetadata.interfaceName = removeLeadingNamespacing(refMetadata.interfaceName);
7183
// reference.name (Mandatory)
7284
ObjectValidator(metadata, "name").AssignValueTo(refMetadata.name);
7385

@@ -271,5 +283,5 @@ namespace cppmicroservices
271283
}
272284

273285
} // namespace metadata
274-
} // namespace scrimpl
286+
} // namespace scrimpl
275287
} // namespace cppmicroservices

compendium/DeclarativeServices/test/gtest/TestComponentConfigurationImpl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ namespace cppmicroservices
742742
EXPECT_CALL(*mockFactory, GetService(testing::_, testing::_))
743743
.Times(1)
744744
.WillRepeatedly(testing::Invoke(
745-
[&](const cppmicroservices::Bundle& b, const cppmicroservices::ServiceRegistrationBase&)
745+
[&](cppmicroservices::Bundle const& b, cppmicroservices::ServiceRegistrationBase const&)
746746
{
747747
fakeCompConfig->Activate(b);
748748
return instanceMap;

compendium/DeclarativeServices/test/gtest/TestMetadataParserImplV1.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,23 @@ namespace
168168
ASSERT_EQ(component->implClassName, "Foo::Impl2");
169169
}
170170

171+
TEST_F(MetadataParserImplV1Test, ParseValidManifestWithGlobalNamespacing)
172+
{
173+
auto metadataparser = MetadataParserFactory::Create(1, GetLogger());
174+
auto components
175+
= metadataparser->ParseAndGetComponentsMetadata(ManifestHelper::GetTestManifest("valid_manifest_with_global_namespacing"));
176+
auto const component = components[0];
177+
ASSERT_EQ(component->activateMethodName, std::string("Activate"));
178+
ASSERT_EQ(component->deactivateMethodName, std::string("Deactivate"));
179+
ASSERT_EQ(component->modifiedMethodName, std::string("Modified"));
180+
ASSERT_EQ(component->immediate, false);
181+
ASSERT_EQ(component->enabled, true);
182+
ASSERT_EQ(component->name, "DSSpellCheck::SpellCheckImpl");
183+
ASSERT_EQ(component->implClassName, "DSSpellCheck::SpellCheckImpl");
184+
ASSERT_THAT(component->properties, ::testing::SizeIs(0));
185+
}
186+
187+
171188
// For the SCR map specified in "scr", we expect the exception message
172189
// output by the Metadata Parser to be exactly errorOutput.
173190
// Instead, if we expect the errorOutput to be contained in the generated error message,

compendium/DeclarativeServices/test/gtest/manifest.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,22 @@
6060
}]
6161
}
6262
},
63+
"valid_manifest_with_global_namespacing": {
64+
"scr": {
65+
"version": 1,
66+
"components": [{
67+
"implementation-class": "DSSpellCheck::SpellCheckImpl",
68+
"service": {
69+
"scope": "singleton",
70+
"interfaces": ["::SpellCheck::ISpellCheckService"]
71+
},
72+
"references": [{
73+
"name": "dictionary",
74+
"interface": "::DictionaryService::IDictionaryService"
75+
}]
76+
}]
77+
}
78+
},
6379
"manifest_dyn": {
6480
"scr": {
6581
"version": 1,

framework/src/service/ServiceRegistry.cpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,17 @@
3636
namespace cppmicroservices
3737
{
3838

39+
std::string
40+
removeLeadingNamespacing(std::string const& className)
41+
{
42+
auto ind = className.find_first_not_of(':');
43+
if (ind == std::string::npos)
44+
{
45+
return className;
46+
}
47+
return className.substr(ind);
48+
}
49+
3950
void
4051
ServiceRegistry::Clear()
4152
{
@@ -93,10 +104,10 @@ namespace cppmicroservices
93104

94105
// Check if we got a service factory
95106
bool isFactory = service->count("org.cppmicroservices.factory") > 0;
96-
bool isPrototypeFactory
97-
= (isFactory ? static_cast<bool>(std::dynamic_pointer_cast<PrototypeServiceFactory>(
98-
std::static_pointer_cast<ServiceFactory>(service->find("org.cppmicroservices.factory")->second)))
99-
: false);
107+
bool isPrototypeFactory = (isFactory ? static_cast<bool>(std::dynamic_pointer_cast<PrototypeServiceFactory>(
108+
std::static_pointer_cast<ServiceFactory>(
109+
service->find("org.cppmicroservices.factory")->second)))
110+
: false);
100111

101112
std::vector<std::string> classes;
102113
// Check if service implements claimed classes and that they exist.
@@ -106,7 +117,7 @@ namespace cppmicroservices
106117
{
107118
throw std::invalid_argument("Can't register as null class");
108119
}
109-
classes.push_back(i.first);
120+
classes.push_back(removeLeadingNamespacing(i.first));
110121
}
111122

112123
ServiceRegistrationBase res(bundle,
@@ -148,7 +159,7 @@ namespace cppmicroservices
148159
void
149160
ServiceRegistry::Get(std::string const& clazz, std::vector<ServiceRegistrationBase>& serviceRegs) const
150161
{
151-
this->Lock(), Get_unlocked(clazz, serviceRegs);
162+
this->Lock(), Get_unlocked(removeLeadingNamespacing(clazz), serviceRegs);
152163
}
153164

154165
void
@@ -169,7 +180,7 @@ namespace cppmicroservices
169180
try
170181
{
171182
std::vector<ServiceReferenceBase> srs;
172-
Get_unlocked(clazz, "", bundle, srs);
183+
Get_unlocked(removeLeadingNamespacing(clazz), "", bundle, srs);
173184
DIAG_LOG(*core->sink) << "get service ref " << clazz << " for bundle " << bundle->symbolicName << " = "
174185
<< srs.size() << " refs";
175186

@@ -191,7 +202,7 @@ namespace cppmicroservices
191202
BundlePrivate* bundle,
192203
std::vector<ServiceReferenceBase>& res) const
193204
{
194-
this->Lock(), Get_unlocked(clazz, filter, bundle, res);
205+
this->Lock(), Get_unlocked(removeLeadingNamespacing(clazz), filter, bundle, res);
195206
}
196207

197208
void

framework/test/gtest/ServiceRegistryTest.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,33 @@ TEST_F(ServiceRegistryTest, TestServiceInterfaceId)
7979
{
8080
ASSERT_EQ(us_service_interface_iid<int>(), "int");
8181
ASSERT_EQ(us_service_interface_iid<ITestServiceA>(), "ITestServiceA");
82+
ASSERT_EQ(us_service_interface_iid<::ITestServiceA>(), "ITestServiceA");
8283
ASSERT_EQ(us_service_interface_iid<ITestServiceB>(), "com.mycompany.ITestService/1.0");
8384
}
8485

86+
TEST_F(ServiceRegistryTest, TestGlobalNamespaceOnServiceRegistration)
87+
{
88+
auto s1 = std::make_shared<TestServiceA>();
89+
90+
ServiceRegistration<ITestServiceA> reg1 = context.RegisterService<::ITestServiceA>(s1);
91+
92+
// Test for two registered ITestServiceA services
93+
ServiceReference<ITestServiceA> ref = context.GetServiceReference("ITestServiceA");
94+
ASSERT_TRUE(ref);
95+
96+
ref = context.GetServiceReference("::ITestServiceA");
97+
ASSERT_TRUE(ref);
98+
99+
// Test for no ITestServiceA services
100+
reg1.Unregister();
101+
ref = context.GetServiceReference("::ITestServiceA");
102+
ASSERT_FALSE(ref);
103+
104+
// Test for invalid service reference
105+
ref = context.GetServiceReference<ITestServiceA>();
106+
ASSERT_FALSE(ref);
107+
}
108+
85109
TEST_F(ServiceRegistryTest, TestMultipleServiceRegistrations)
86110
{
87111
auto s1 = std::make_shared<TestServiceA>();

0 commit comments

Comments
 (0)