Skip to content

Commit

Permalink
[WFLY-12190] EJB: EJB over HTTP discovery configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
tadamski committed Jan 8, 2020
1 parent 0513207 commit 348863d
Show file tree
Hide file tree
Showing 18 changed files with 301 additions and 23 deletions.
Expand Up @@ -22,10 +22,12 @@

package org.jboss.as.ee.metadata;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
Expand All @@ -45,6 +47,7 @@ public class EJBClientDescriptorMetaData {
private String profile;

private Map<String, RemotingReceiverConfiguration> remotingReceiverConfigurations = new HashMap<String, RemotingReceiverConfiguration>();
private List<HttpConnectionConfiguration> httpConnectionConfigurations = new ArrayList<>();
private Set<ClusterConfig> clusterConfigs = new HashSet<ClusterConfig>();


Expand Down Expand Up @@ -73,6 +76,10 @@ public Collection<RemotingReceiverConfiguration> getRemotingReceiverConfiguratio
return this.remotingReceiverConfigurations.values();
}

public List<HttpConnectionConfiguration> getHttpConnectionConfigurations() {
return httpConnectionConfigurations;
}

/**
* Set the pass-by-value semantics for the local receiver belonging to the EJB client context
* represented by this metadata
Expand Down Expand Up @@ -339,4 +346,16 @@ public int hashCode() {
return outboundConnectionRef != null ? outboundConnectionRef.hashCode() : 0;
}
}

public class HttpConnectionConfiguration {
private final String uri;

HttpConnectionConfiguration(final String uri) {
this.uri = uri;
}

public String getUri() {
return uri;
}
}
}
5 changes: 5 additions & 0 deletions ejb3/pom.xml
Expand Up @@ -216,6 +216,11 @@ projects that depend on this project.-->
<artifactId>undertow-server</artifactId>
</dependency>

<dependency>
<groupId>org.wildfly.wildfly-http-client</groupId>
<artifactId>wildfly-http-ejb-client</artifactId>
</dependency>

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
Expand Down
Expand Up @@ -40,6 +40,8 @@
import org.wildfly.discovery.impl.StaticDiscoveryProvider;
import org.wildfly.discovery.spi.DiscoveryProvider;

import org.wildfly.httpclient.ejb.HttpEJBDiscoveryProvider;

/**
* Processor responsible for ensuring that the discovery service for each deployment unit exists.
*
Expand Down Expand Up @@ -76,6 +78,7 @@ public void uninject() {
providerInjector.uninject();
}
});
discoveryService.getDiscoveryProviderInjector().inject(new HttpEJBDiscoveryProvider());

// only add association service dependency if the context is configured to use the local EJB receiver & we are not app client

Expand Down
Expand Up @@ -181,8 +181,9 @@ public void uninject() {
// if descriptor defines list of ejb-receivers instead of profile then we create internal ProfileService for this
// application which contains defined receivers
profileServiceName = ejbClientContextServiceName.append(INTERNAL_REMOTING_PROFILE);
final Map<String, RemotingProfileService.ConnectionSpec> map = new HashMap<>();
final RemotingProfileService profileService = new RemotingProfileService(Collections.emptyList(), map);
final Map<String, RemotingProfileService.RemotingConnectionSpec> remotingConnectionMap = new HashMap<>();
final List<RemotingProfileService.HttpConnectionSpec> httpConnections = new ArrayList<>();
final RemotingProfileService profileService = new RemotingProfileService(Collections.emptyList(), remotingConnectionMap, httpConnections);
final ServiceBuilder<RemotingProfileService> profileServiceBuilder = serviceTarget.addService(profileServiceName,
profileService);
if (ejbClientDescriptorMetaData.isLocalReceiverExcluded() != Boolean.TRUE) {
Expand All @@ -197,8 +198,13 @@ public void uninject() {
final OptionMap optionMap = getOptionMapFromProperties(channelCreationOptions, EJBClientDescriptorMetaDataProcessor.class.getClassLoader());
final InjectedValue<AbstractOutboundConnectionService> injector = new InjectedValue<>();
profileServiceBuilder.addDependency(AbstractOutboundConnectionService.OUTBOUND_CONNECTION_BASE_SERVICE_NAME.append(connectionRef), AbstractOutboundConnectionService.class, injector);
final RemotingProfileService.ConnectionSpec connectionSpec = new RemotingProfileService.ConnectionSpec(connectionRef, injector, optionMap, connectTimeout);
map.put(connectionRef, connectionSpec);
final RemotingProfileService.RemotingConnectionSpec connectionSpec = new RemotingProfileService.RemotingConnectionSpec(connectionRef, injector, optionMap, connectTimeout);
remotingConnectionMap.put(connectionRef, connectionSpec);
}
for (EJBClientDescriptorMetaData.HttpConnectionConfiguration httpConfigurations : ejbClientDescriptorMetaData.getHttpConnectionConfigurations()) {
final String uri = httpConfigurations.getUri();
RemotingProfileService.HttpConnectionSpec httpConnectionSpec = new RemotingProfileService.HttpConnectionSpec(uri);
httpConnections.add(httpConnectionSpec);
}
profileServiceBuilder.install();

Expand Down
Expand Up @@ -180,7 +180,7 @@ public void start(StartContext context) throws StartException {
AuthenticationContext transformed = finalAuthenticationContext;
// now transform it
if (profileService != null) {
for (RemotingProfileService.ConnectionSpec connectionSpec : profileService.getConnectionSpecs()) {
for (RemotingProfileService.RemotingConnectionSpec connectionSpec : profileService.getConnectionSpecs()) {
transformed = transformOne(connectionSpec, transformed);
}
}
Expand Down Expand Up @@ -219,7 +219,7 @@ public Void getValue() throws IllegalStateException, IllegalArgumentException {
return null;
}

private static AuthenticationContext transformOne(RemotingProfileService.ConnectionSpec connectionSpec, AuthenticationContext context) {
private static AuthenticationContext transformOne(RemotingProfileService.RemotingConnectionSpec connectionSpec, AuthenticationContext context) {
final AbstractOutboundConnectionService connectionService = connectionSpec.getInjector().getValue();
AuthenticationConfiguration authenticationConfiguration = connectionService.getAuthenticationConfiguration();
SSLContext sslContext = connectionService.getSSLContext();
Expand Down
Expand Up @@ -110,11 +110,18 @@ public void start(final StartContext context) throws StartException {
}

final RemotingProfileService profileService = profileServiceInjector.getOptionalValue();
if (profileService != null) for (RemotingProfileService.ConnectionSpec spec : profileService.getConnectionSpecs()) {
final EJBClientConnection.Builder connBuilder = new EJBClientConnection.Builder();
connBuilder.setDestination(spec.getInjector().getValue().getDestinationUri());
// connBuilder.setConnectionTimeout(timeout);
builder.addClientConnection(connBuilder.build());
if (profileService != null) {
for (RemotingProfileService.RemotingConnectionSpec spec : profileService.getConnectionSpecs()) {
final EJBClientConnection.Builder connBuilder = new EJBClientConnection.Builder();
connBuilder.setDestination(spec.getInjector().getValue().getDestinationUri());
// connBuilder.setConnectionTimeout(timeout);
builder.addClientConnection(connBuilder.build());
}
for (RemotingProfileService.HttpConnectionSpec spec : profileService.getHttpConnectionSpecs()) {
final EJBClientConnection.Builder connBuilder = new EJBClientConnection.Builder();
connBuilder.setDestination(spec.getUri());
builder.addClientConnection(connBuilder.build());
}
}
if(appClientUri.getOptionalValue() != null) {
final EJBClientConnection.Builder connBuilder = new EJBClientConnection.Builder();
Expand Down
Expand Up @@ -33,6 +33,7 @@
import org.wildfly.discovery.ServiceURL;
import org.xnio.OptionMap;

import java.net.URI;
import java.util.Collection;
import java.util.List;
import java.util.Map;
Expand All @@ -52,12 +53,15 @@ public class RemotingProfileService implements Service<RemotingProfileService> {
* There URLs are used to allow discovery to find these connections.
*/
private final List<ServiceURL> serviceUrls;
private final Map<String, ConnectionSpec> connectionSpecMap;
private final Map<String, RemotingConnectionSpec> remotingConnectionSpecMap;
private final List<HttpConnectionSpec> httpConnectionSpecs;
private final InjectedValue<EJBTransportProvider> localTransportProviderInjector = new InjectedValue<>();

public RemotingProfileService(final List<ServiceURL> serviceUrls, final Map<String, ConnectionSpec> connectionSpecMap) {
public RemotingProfileService(final List<ServiceURL> serviceUrls, final Map<String, RemotingConnectionSpec> remotingConnectionSpecMap,
final List<HttpConnectionSpec> httpConnectionSpecs) {
this.serviceUrls = serviceUrls;
this.connectionSpecMap = connectionSpecMap;
this.remotingConnectionSpecMap = remotingConnectionSpecMap;
this.httpConnectionSpecs = httpConnectionSpecs;
}

@Override
Expand All @@ -73,8 +77,12 @@ public void start(StartContext context) throws StartException {
public void stop(StopContext context) {
}

public Collection<ConnectionSpec> getConnectionSpecs() {
return connectionSpecMap.values();
public Collection<RemotingConnectionSpec> getConnectionSpecs() {
return remotingConnectionSpecMap.values();
}

public Collection<HttpConnectionSpec> getHttpConnectionSpecs() {
return httpConnectionSpecs;
}

public List<ServiceURL> getServiceUrls() {
Expand All @@ -85,13 +93,13 @@ public InjectedValue<EJBTransportProvider> getLocalTransportProviderInjector() {
return localTransportProviderInjector;
}

public static final class ConnectionSpec {
public static final class RemotingConnectionSpec {
private final String connectionName;
private final InjectedValue<AbstractOutboundConnectionService> injector;
private final OptionMap connectOptions;
private final long connectTimeout;

public ConnectionSpec(final String connectionName, final InjectedValue<AbstractOutboundConnectionService> injector, final OptionMap connectOptions, final long connectTimeout) {
public RemotingConnectionSpec(final String connectionName, final InjectedValue<AbstractOutboundConnectionService> injector, final OptionMap connectOptions, final long connectTimeout) {
this.connectionName = connectionName;
this.injector = injector;
this.connectOptions = connectOptions;
Expand All @@ -114,4 +122,20 @@ public long getConnectTimeout() {
return connectTimeout;
}
}

public static final class HttpConnectionSpec {
private final String uri;

public HttpConnectionSpec(final String uri) {
this.uri = uri;
}

public URI getUri() {
try {
return new URI(uri);
} catch(Exception e) {
return null;
}
}
}
}
Expand Up @@ -264,7 +264,7 @@ protected void parseProfile(final XMLExtendedStreamReader reader, List<ModelNode
}
}

private ModelNode parseStaticEjbDiscoveryType(final XMLExtendedStreamReader reader) throws XMLStreamException {
protected ModelNode parseStaticEjbDiscoveryType(final XMLExtendedStreamReader reader) throws XMLStreamException {
ModelNode staticDiscovery = new ModelNode();
while (reader.hasNext() && reader.nextTag() != END_ELEMENT) {
switch (EJB3SubsystemXMLElement.forName(reader.getLocalName())) {
Expand Down
@@ -1,6 +1,6 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2019, Red Hat, Inc., and individual contributors
* Copyright 2020, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
Expand All @@ -22,13 +22,21 @@

package org.jboss.as.ejb3.subsystem;

import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.operations.common.Util;
import org.jboss.dmr.ModelNode;
import org.jboss.ejb.client.EJBClientContext;
import org.jboss.staxmapper.XMLExtendedStreamReader;

import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;

import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
import static org.jboss.as.controller.parsing.ParseUtils.missingRequired;
import static org.jboss.as.controller.parsing.ParseUtils.requireNoAttributes;
import static org.jboss.as.controller.parsing.ParseUtils.requireNoContent;
import static org.jboss.as.controller.parsing.ParseUtils.requireNoNamespaceAttribute;
Expand Down Expand Up @@ -133,4 +141,102 @@ protected void parseInterceptor(final XMLExtendedStreamReader reader, final Mode

interceptors.add(interceptor);
}

protected void parseProfile(final XMLExtendedStreamReader reader, List<ModelNode> operations) throws XMLStreamException {
final int count = reader.getAttributeCount();
String profileName = null;

final EJBClientContext.Builder builder = new EJBClientContext.Builder();

final ModelNode operation = Util.createAddOperation();

for (int i = 0; i < count; i++) {
requireNoNamespaceAttribute(reader, i);
final String value = reader.getAttributeValue(i);
final EJB3SubsystemXMLAttribute attribute = EJB3SubsystemXMLAttribute.forName(reader.getAttributeLocalName(i));
switch (attribute) {
case NAME:
profileName = value;
break;
case EXCLUDE_LOCAL_RECEIVER:
RemotingProfileResourceDefinition.EXCLUDE_LOCAL_RECEIVER.parseAndSetParameter(value, operation, reader);
break;
case LOCAL_RECEIVER_PASS_BY_VALUE:
RemotingProfileResourceDefinition.LOCAL_RECEIVER_PASS_BY_VALUE.parseAndSetParameter(value, operation, reader);
break;
default:
throw unexpectedAttribute(reader, i);
}
}

if (profileName == null) {
throw missingRequired(reader, Collections.singleton(EJB3SubsystemXMLAttribute.NAME.getLocalName()));
}


final PathAddress address = SUBSYSTEM_PATH.append(EJB3SubsystemModel.REMOTING_PROFILE, profileName);
operation.get(OP_ADDR).set(address.toModelNode());
operations.add(operation);

while (reader.hasNext() && reader.nextTag() != XMLStreamConstants.END_ELEMENT) {
switch (EJB3SubsystemXMLElement.forName(reader.getLocalName())) {
case STATIC_EJB_DISCOVERY:
final ModelNode staticEjb = parseStaticEjbDiscoveryType(reader);
operation.get(StaticEJBDiscoveryDefinition.STATIC_EJB_DISCOVERY).set(staticEjb);
break;
case REMOTING_EJB_RECEIVER: {
parseRemotingReceiver(reader, address, operations);
break;
}
case REMOTE_HTTP_CONNECTION:
parseRemoteHttpConnection(reader, address, operations);
break;
default: {
throw unexpectedElement(reader);
}
}
}
}

protected void parseRemoteHttpConnection(final XMLExtendedStreamReader reader, final PathAddress profileAddress,
final List<ModelNode> operations) throws XMLStreamException {

final ModelNode operation = Util.createAddOperation();

String name = null;
final Set<EJB3SubsystemXMLAttribute> required = EnumSet.of(EJB3SubsystemXMLAttribute.URI);
final int count = reader.getAttributeCount();
for (int i = 0; i < count; i++) {
final String value = reader.getAttributeValue(i);
final EJB3SubsystemXMLAttribute attribute = EJB3SubsystemXMLAttribute.forName(reader.getAttributeLocalName(i));
required.remove(attribute);
switch (attribute) {
case NAME:
name = value;
break;
case URI:
RemoteHttpConnectionDefinition.URI.parseAndSetParameter(value, operation, reader);
break;
default:
throw unexpectedAttribute(reader, i);
}
}
if (!required.isEmpty()) {
throw missingRequired(reader, required);
}

final PathAddress receiverAddress = profileAddress.append(EJB3SubsystemModel.REMOTE_HTTP_CONNECTION, name);
operation.get(OP_ADDR).set(receiverAddress.toModelNode());
operations.add(operation);

while (reader.hasNext() && reader.nextTag() != XMLStreamConstants.END_ELEMENT) {
switch (EJB3SubsystemXMLElement.forName(reader.getLocalName())) {
case CHANNEL_CREATION_OPTIONS:
parseChannelCreationOptions(reader, receiverAddress, operations);
break;
default:
throw unexpectedElement(reader);
}
}
}
}
Expand Up @@ -96,6 +96,7 @@ public interface EJB3SubsystemModel {
String OUTBOUND_CONNECTION_REF= "outbound-connection-ref";
String CONNECT_TIMEOUT= "connect-timeout";
String CLIENT_MAPPINGS_CLUSTER_NAME = "cluster";
String REMOTE_HTTP_CONNECTION = "remote-http-connection";

String TIMER = "timer";
String TIMER_SERVICE = "timer-service";
Expand Down Expand Up @@ -171,5 +172,6 @@ public interface EJB3SubsystemModel {
String CLASS = "class";
String BINDING = "binding";

String URI = "uri";

}
Expand Up @@ -79,6 +79,7 @@ public enum EJB3SubsystemXMLElement {

REMOTE("remote"),
REMOTING_EJB_RECEIVER("remoting-ejb-receiver"),
REMOTE_HTTP_CONNECTION("remote-http-connection"),
RESOURCE_ADAPTER_NAME("resource-adapter-name"),
RESOURCE_ADAPTER_REF("resource-adapter-ref"),

Expand Down

0 comments on commit 348863d

Please sign in to comment.