Skip to content

Commit ff795a8

Browse files
authored
4.x: Update to ServiceRegistry API to add helper methods for qualified instances (helidon-io#10324)
* API update to services and service registry. * Added methods with qualifiers * Added methods for named instances * Added late binding methods for qualified instances.
1 parent d19cc0c commit ff795a8

5 files changed

Lines changed: 593 additions & 6 deletions

File tree

service/registry/src/main/java/io/helidon/service/registry/CoreServiceRegistry.java

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,63 @@ <T> void add(Class<T> contract, double weight, T instance) {
482482
}
483483
}
484484

485+
@SuppressWarnings("unchecked")
486+
<T> void setQualified(Class<T> contract, T instance, Set<Qualifier> qualifiers) {
487+
if (!allowLateBinding) {
488+
throw new ServiceRegistryException("This service registry instance does not support late binding, as it was "
489+
+ "explicitly disabled through registry configuration: " + id);
490+
}
491+
492+
stateWriteLock.lock();
493+
try {
494+
ResolvedType contractType = ResolvedType.create(contract);
495+
checkValidContract(contractType);
496+
ServiceInfo serviceInfo = servicesByType.get(contractType.type());
497+
if (serviceInfo != null && !serviceInfo.qualifiers().equals(qualifiers)) {
498+
throw new IllegalArgumentException("Attempting to create a qualified service instance for "
499+
+ "a service implementation, with wrong qualifiers: "
500+
+ contract.getName() + ", qualifiers: " + qualifiers);
501+
}
502+
if (serviceInfo == null) {
503+
Set<ServiceInfo> serviceInfos = new TreeSet<>(SERVICE_INFO_COMPARATOR);
504+
505+
// we need to keep order of the instances; if somebody calls set, and then add, it may be tricky
506+
507+
VirtualDescriptor vt = new VirtualDescriptor(contractType.type(), Weighted.DEFAULT_WEIGHT, instance, qualifiers);
508+
509+
ServiceProvider<Object> provider = new ServiceProvider<>(this, vt);
510+
Activator<Object> activator = Activators.create(provider, instance);
511+
512+
servicesByDescriptor.put(vt, new ServiceManager<>(this,
513+
scopeSupplier(vt),
514+
provider,
515+
true,
516+
() -> activator));
517+
serviceInfos.add(vt);
518+
519+
// replace the instances
520+
servicesByContract.put(contractType, serviceInfos);
521+
} else {
522+
// this is a service instance, not contract implementation (i.e. the contract is actual service class)
523+
ServiceProvider<Object> provider = new ServiceProvider<>(this,
524+
(ServiceDescriptor<Object>) serviceInfo);
525+
526+
Activator<Object> activator = Activators.create(provider, instance);
527+
servicesByDescriptor.put(serviceInfo, new ServiceManager<>(this,
528+
scopeSupplier(serviceInfo),
529+
provider,
530+
true,
531+
() -> activator));
532+
}
533+
// reset bindings, as build-time binding would ignore instances explicitly set
534+
bindings.forgetContract(contractType);
535+
} finally {
536+
stateWriteLock.unlock();
537+
}
538+
539+
stateWriteLock.lock();
540+
}
541+
485542
@SuppressWarnings("unchecked")
486543
<T> void set(Class<T> contract, T[] instances) {
487544
if (!allowLateBinding) {

0 commit comments

Comments
 (0)