Skip to content

Commit 2d47f03

Browse files
authored
Merge pull request wildfly#18838 from pferraro/WFLY-19483
WFLY-19483 Migrate singleton subsystem to wildfly-subsystem
2 parents 9490288 + aaa2cdd commit 2d47f03

File tree

40 files changed

+780
-1146
lines changed

40 files changed

+780
-1146
lines changed

clustering/singleton/api/src/main/java/org/wildfly/clustering/singleton/election/SingletonElectionPolicy.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,18 @@ public interface SingletonElectionPolicy {
2828
GroupMember elect(List<GroupMember> candidates);
2929

3030
default SingletonElectionPolicy prefer(List<Predicate<GroupMember>> preferences) {
31-
SingletonElectionPolicy policy = this;
32-
return new SingletonElectionPolicy() {
31+
return !preferences.isEmpty() ? new SingletonElectionPolicy() {
3332
@Override
3433
public GroupMember elect(List<GroupMember> candidates) {
3534
for (Predicate<GroupMember> preference : preferences) {
3635
List<GroupMember> preferred = candidates.stream().filter(preference).collect(Collectors.toUnmodifiableList());
3736
if (!preferred.isEmpty()) {
38-
return policy.elect(preferred);
37+
return SingletonElectionPolicy.this.elect(preferred);
3938
}
4039
}
41-
return policy.elect(candidates);
40+
return SingletonElectionPolicy.this.elect(candidates);
4241
}
43-
};
42+
} : this;
4443
}
4544

4645
static SingletonElectionPolicy random() {

clustering/singleton/extension/src/main/java/org/wildfly/extension/clustering/singleton/ElectionPolicyResourceDefinition.java

Lines changed: 0 additions & 152 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
/*
2+
* Copyright The WildFly Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package org.wildfly.extension.clustering.singleton;
7+
8+
import java.util.Collections;
9+
import java.util.LinkedList;
10+
import java.util.List;
11+
import java.util.function.Predicate;
12+
import java.util.function.Supplier;
13+
import java.util.function.UnaryOperator;
14+
import java.util.stream.Collectors;
15+
16+
import javax.xml.stream.XMLStreamException;
17+
18+
import org.infinispan.manager.EmbeddedCacheManager;
19+
import org.infinispan.remoting.transport.jgroups.JGroupsTransport;
20+
import org.jboss.as.controller.AttributeDefinition;
21+
import org.jboss.as.controller.AttributeMarshaller;
22+
import org.jboss.as.controller.AttributeParser;
23+
import org.jboss.as.controller.AttributeParsers;
24+
import org.jboss.as.controller.DefaultAttributeMarshaller;
25+
import org.jboss.as.controller.OperationContext;
26+
import org.jboss.as.controller.OperationFailedException;
27+
import org.jboss.as.controller.ResourceDefinition;
28+
import org.jboss.as.controller.ResourceRegistration;
29+
import org.jboss.as.controller.StringListAttributeDefinition;
30+
import org.jboss.as.controller.capability.RuntimeCapability;
31+
import org.jboss.as.controller.capability.UnaryCapabilityNameResolver;
32+
import org.jboss.as.controller.descriptions.ResourceDescriptionResolver;
33+
import org.jboss.as.controller.registry.AttributeAccess;
34+
import org.jboss.as.controller.registry.ManagementResourceRegistration;
35+
import org.jboss.as.controller.registry.Resource;
36+
import org.jboss.as.network.OutboundSocketBinding;
37+
import org.jboss.dmr.ModelNode;
38+
import org.jboss.staxmapper.XMLExtendedStreamReader;
39+
import org.wildfly.clustering.infinispan.service.InfinispanServiceDescriptor;
40+
import org.wildfly.clustering.server.GroupMember;
41+
import org.wildfly.clustering.singleton.election.SingletonElectionPolicy;
42+
import org.wildfly.extension.clustering.singleton.election.OutboundSocketBindingPreference;
43+
import org.wildfly.service.descriptor.UnaryServiceDescriptor;
44+
import org.wildfly.subsystem.resource.ChildResourceDefinitionRegistrar;
45+
import org.wildfly.subsystem.resource.ManagementResourceRegistrar;
46+
import org.wildfly.subsystem.resource.ManagementResourceRegistrationContext;
47+
import org.wildfly.subsystem.resource.ResourceDescriptor;
48+
import org.wildfly.subsystem.resource.ResourceModelResolver;
49+
import org.wildfly.subsystem.resource.capability.CapabilityReference;
50+
import org.wildfly.subsystem.resource.capability.CapabilityReferenceListAttributeDefinition;
51+
import org.wildfly.subsystem.resource.operation.ResourceOperationRuntimeHandler;
52+
import org.wildfly.subsystem.service.ResourceServiceConfigurator;
53+
import org.wildfly.subsystem.service.ResourceServiceInstaller;
54+
import org.wildfly.subsystem.service.ServiceDependency;
55+
import org.wildfly.subsystem.service.capability.CapabilityServiceInstaller;
56+
57+
/**
58+
* Registers a resource definition of an election policy.
59+
* @author Paul Ferraro
60+
*/
61+
public abstract class ElectionPolicyResourceDefinitionRegistrar implements ChildResourceDefinitionRegistrar, ResourceServiceConfigurator, ResourceModelResolver<SingletonElectionPolicy>, UnaryOperator<ResourceDescriptor.Builder> {
62+
63+
private static final RuntimeCapability<Void> CAPABILITY = RuntimeCapability.Builder.of(SingletonElectionPolicy.SERVICE_DESCRIPTOR).setDynamicNameMapper(UnaryCapabilityNameResolver.PARENT).build();
64+
65+
private static final AttributeMarshaller PREFERENCES_MARSHALLER = new DefaultAttributeMarshaller() {
66+
@Override
67+
public boolean isMarshallableAsElement() {
68+
return true;
69+
}
70+
71+
@Override
72+
protected String asString(ModelNode value) {
73+
return value.asListOrEmpty().stream().map(ModelNode::asString).collect(Collectors.joining(" "));
74+
}
75+
};
76+
private static final AttributeParser PREFERENCES_PARSER = new AttributeParsers.AttributeElementParser() {
77+
@Override
78+
public void parseElement(AttributeDefinition attribute, XMLExtendedStreamReader reader, ModelNode operation) throws XMLStreamException {
79+
ModelNode list = operation.get(attribute.getName()).setEmptyList();
80+
for (String value : reader.getElementText().split("\\s+")) {
81+
list.add(new ModelNode(value));
82+
}
83+
}
84+
};
85+
private static final String NAME_PREFERENCES_NAME = "name-preferences";
86+
static final CapabilityReferenceListAttributeDefinition<OutboundSocketBinding> SOCKET_BINDING_PREFERENCES = new CapabilityReferenceListAttributeDefinition.Builder<>("socket-binding-preferences", CapabilityReference.builder(CAPABILITY, OutboundSocketBinding.SERVICE_DESCRIPTOR).build())
87+
.setRequired(false)
88+
.setAlternatives(NAME_PREFERENCES_NAME)
89+
.setAttributeMarshaller(PREFERENCES_MARSHALLER)
90+
.setAttributeParser(PREFERENCES_PARSER)
91+
.build();
92+
static final AttributeDefinition NAME_PREFERENCES = new StringListAttributeDefinition.Builder(NAME_PREFERENCES_NAME)
93+
.setAllowExpression(true)
94+
.setRequired(false)
95+
.setAlternatives(SOCKET_BINDING_PREFERENCES.getName())
96+
.setAttributeMarshaller(PREFERENCES_MARSHALLER)
97+
.setAttributeParser(PREFERENCES_PARSER)
98+
.setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
99+
.build();
100+
101+
private final ResourceRegistration registration;
102+
103+
ElectionPolicyResourceDefinitionRegistrar(ResourceRegistration registration) {
104+
this.registration = registration;
105+
}
106+
107+
@Override
108+
public ResourceDescriptor.Builder apply(ResourceDescriptor.Builder builder) {
109+
return builder.addCapability(CAPABILITY)
110+
.addAttributes(List.of(SOCKET_BINDING_PREFERENCES, NAME_PREFERENCES))
111+
.withRuntimeHandler(ResourceOperationRuntimeHandler.configureService(this))
112+
;
113+
}
114+
115+
@Override
116+
public ManagementResourceRegistration register(ManagementResourceRegistration parent, ManagementResourceRegistrationContext context) {
117+
ResourceDescriptionResolver resolver = SingletonSubsystemResourceDefinitionRegistrar.RESOLVER.createChildResolver(this.registration.getPathElement(), ElectionPolicyResourceRegistration.WILDCARD.getPathElement());
118+
ResourceDescriptor descriptor = this.apply(ResourceDescriptor.builder(resolver)).build();
119+
ManagementResourceRegistration registration = parent.registerSubModel(ResourceDefinition.builder(this.registration, resolver).build());
120+
ManagementResourceRegistrar.of(descriptor).register(registration);
121+
return registration;
122+
}
123+
124+
@Override
125+
public ResourceServiceInstaller configure(OperationContext context, ModelNode model) throws OperationFailedException {
126+
List<ModelNode> namePreferences = NAME_PREFERENCES.resolveModelAttribute(context, model).asListOrEmpty();
127+
List<ModelNode> socketBindingPreferences = SOCKET_BINDING_PREFERENCES.resolveModelAttribute(context, model).asListOrEmpty();
128+
SingletonElectionPolicy electionPolicy = this.resolve(context, model);
129+
List<Predicate<GroupMember>> preferences = new LinkedList<>();
130+
CapabilityServiceInstaller.Builder<SingletonElectionPolicy, SingletonElectionPolicy> builder = CapabilityServiceInstaller.builder(CAPABILITY, new Supplier<>() {
131+
@Override
132+
public SingletonElectionPolicy get() {
133+
return electionPolicy.prefer(Collections.unmodifiableList(preferences));
134+
}
135+
});
136+
if (!socketBindingPreferences.isEmpty()) {
137+
Resource policy = context.readResourceFromRoot(context.getCurrentAddress().getParent(), false);
138+
String containerName = SingletonPolicyResourceDefinitionRegistrar.CACHE_ATTRIBUTE_GROUP.getContainerAttribute().resolveModelAttribute(context, policy.getModel()).asString();
139+
UnaryServiceDescriptor<Void> containerTransportChannel = UnaryServiceDescriptor.of(String.join(".", InfinispanServiceDescriptor.CACHE_CONTAINER_CONFIGURATION.getName(), "transport", "jgroups"), Void.class);
140+
if (context.hasOptionalCapability(containerTransportChannel, containerName, CAPABILITY, SOCKET_BINDING_PREFERENCES)) {
141+
ServiceDependency<EmbeddedCacheManager> container = ServiceDependency.on(InfinispanServiceDescriptor.CACHE_CONTAINER, containerName);
142+
builder.requires(container);
143+
for (ModelNode socketBindingPreference : socketBindingPreferences) {
144+
ServiceDependency<OutboundSocketBinding> binding = ServiceDependency.on(OutboundSocketBinding.SERVICE_DESCRIPTOR, socketBindingPreference.asString());
145+
builder.requires(binding);
146+
preferences.add(new Predicate<GroupMember>() {
147+
private final JGroupsTransport transport = (JGroupsTransport) container.get().getCacheManagerConfiguration().transport().jgroups().transport();
148+
private final Predicate<GroupMember> preference = new OutboundSocketBindingPreference(binding.get(), this.transport.getChannel());
149+
150+
@Override
151+
public boolean test(GroupMember member) {
152+
return this.preference.test(member);
153+
}
154+
155+
@Override
156+
public String toString() {
157+
return this.preference.toString();
158+
}
159+
});
160+
}
161+
}
162+
}
163+
if (!namePreferences.isEmpty()) {
164+
for (ModelNode namePreference : namePreferences) {
165+
String name = namePreference.asString();
166+
preferences.add(new Predicate<GroupMember>() {
167+
@Override
168+
public boolean test(GroupMember member) {
169+
return member.getName().equals(name);
170+
}
171+
172+
@Override
173+
public String toString() {
174+
return name;
175+
}
176+
});
177+
}
178+
}
179+
return builder.build();
180+
}
181+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright The WildFly Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
package org.wildfly.extension.clustering.singleton;
6+
7+
import org.jboss.as.controller.PathElement;
8+
import org.jboss.as.controller.ResourceRegistration;
9+
10+
/**
11+
* Enumerates resource registration for election policies.
12+
* @author Paul Ferraro
13+
*/
14+
public enum ElectionPolicyResourceRegistration implements ResourceRegistration {
15+
WILDCARD(PathElement.WILDCARD_VALUE),
16+
SIMPLE("simple"),
17+
RANDOM("random"),
18+
;
19+
private final PathElement path;
20+
21+
ElectionPolicyResourceRegistration(String value) {
22+
this.path = PathElement.pathElement("election-policy", value);
23+
}
24+
25+
@Override
26+
public PathElement getPathElement() {
27+
return this.path;
28+
}
29+
}

0 commit comments

Comments
 (0)