Skip to content

Commit

Permalink
Add cluster support and more legacy support
Browse files Browse the repository at this point in the history
  • Loading branch information
dmlloyd committed Jan 30, 2017
1 parent 7f88f93 commit c194ef5
Show file tree
Hide file tree
Showing 11 changed files with 317 additions and 56 deletions.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@
<version.org.jboss.logmanager>1.5.2.Final</version.org.jboss.logmanager>
<version.org.jboss.marshalling>2.0.0.Beta2</version.org.jboss.marshalling>
<version.org.jboss.modules>1.4.3.Final</version.org.jboss.modules>
<version.org.jboss.remoting>5.0.0.Beta14</version.org.jboss.remoting>
<version.org.jboss.remoting>5.0.0.Beta15</version.org.jboss.remoting>
<version.org.jboss.spec.javax.ejb>1.0.0.Final</version.org.jboss.spec.javax.ejb>
<version.org.jboss.spec.javax.transaction>1.0.0.Final</version.org.jboss.spec.javax.transaction>
<version.org.jboss.xnio>3.4.2.Final</version.org.jboss.xnio>
<version.org.kohsuke.metainf-services>1.7</version.org.kohsuke.metainf-services>
<version.org.wildfly.common>1.2.0.Beta4</version.org.wildfly.common>
<version.org.wildfly.common>1.2.0.Beta5</version.org.wildfly.common>
<version.org.wildfly.naming.client>1.0.0.Beta8</version.org.wildfly.naming.client>
<version.org.wildfly.discovery>1.0.0.Beta5</version.org.wildfly.discovery>
<version.org.wildfly.security.elytron>1.1.0.Beta17</version.org.wildfly.security.elytron>
Expand Down
2 changes: 1 addition & 1 deletion protocol.txt
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ If a session open request is sent for a bean which is not a stateful bean, then
│││mapping count │
││├───────────────┤
│││┌──────────────┴─┐ - for each mapping count
││││Client Netmask │ - packed integer, LSB 0 = ipv6, 1 = ipv4; bits 4-n are the netmask bits (only bits 1-8 are used)
││││Client Netmask │ - packed integer, LSB 0 = ipv6, 1 = ipv4; bits 1-n are the netmask bits (only bits 1-8 are used)
│││├────────────────┤
││││Client Source IP│ - IP bytes
│││├────────────────┤
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2012, 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.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* http://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.jboss.ejb.protocol.remote;
package org.jboss.ejb._private;

import java.net.Inet4Address;
import java.net.Inet6Address;
Expand All @@ -29,7 +25,7 @@
/**
* @author Jaikiran Pai
*/
class NetworkUtil {
public class NetworkUtil {

private static int getInt(byte[] b, int offs) {
return (b[offs] & 0xff) << 24 | (b[offs + 1] & 0xff) << 16 | (b[offs + 2] & 0xff) << 8 | b[offs + 3] & 0xff;
Expand Down Expand Up @@ -85,9 +81,9 @@ public static boolean belongsToNetwork(final InetAddress address, final InetAddr
}
}

static String formatPossibleIpv6Address(String address) {
public static String formatPossibleIpv6Address(String address) {
if (address == null) {
return address;
return null;
}
if (!address.contains(":")) {
return address;
Expand Down
98 changes: 93 additions & 5 deletions src/main/java/org/jboss/ejb/client/EJBClientContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@

import static java.security.AccessController.doPrivileged;

import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.URI;
import java.security.PrivilegedAction;
import java.util.ArrayList;
Expand All @@ -33,12 +38,15 @@
import java.util.function.Supplier;

import org.jboss.ejb._private.Logs;
import org.jboss.ejb._private.NetworkUtil;
import org.wildfly.common.Assert;
import org.wildfly.common.context.ContextManager;
import org.wildfly.common.context.Contextual;
import org.wildfly.discovery.AttributeValue;
import org.wildfly.discovery.Discovery;
import org.wildfly.discovery.FilterSpec;
import org.wildfly.discovery.ServiceType;
import org.wildfly.discovery.ServiceURL;
import org.wildfly.discovery.ServicesQueue;

/**
Expand Down Expand Up @@ -78,6 +86,10 @@ public final class EJBClientContext extends Attachable implements Contextual<EJB
* The discovery attribute name which contains a cluster name.
*/
public static final String FILTER_ATTR_CLUSTER = "cluster";
/**
* The discovery attribute name for when a rule only applies to a specific source IP address range.
*/
public static final String FILTER_ATTR_SOURCE_IP = "source-ip";

static {
CONTEXT_MANAGER.setGlobalDefaultSupplier(new ConfigurationBasedEJBClientContextSelector());
Expand Down Expand Up @@ -368,27 +380,103 @@ <R, L extends EJBLocator<T>, T> R discoverFirst(L locator, final LocatedAction<R
return performLocatedAction(locator, locatedAction);
}

ServiceURL serviceURL;
try (final ServicesQueue servicesQueue = discover(filterSpec)) {
for (;;) {
final URI uri;
try {
uri = servicesQueue.take();
serviceURL = servicesQueue.takeService();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw Logs.MAIN.operationInterrupted();
}
if (uri == null) {
if (serviceURL == null) {
throw Logs.MAIN.noEJBReceiverAvailable(locator);
}
// check that we support the URI scheme
final URI uri = serviceURL.getLocationURI();
final EJBReceiver receiver = getTransportProvider(uri.getScheme());
if (receiver != null) {
return locatedAction.execute(receiver, locator, Affinity.forUri(uri));
if (receiver == null) {
// unsupported, skip it
continue;
}
// check that we satisfy the service URL
final List<AttributeValue> values = serviceURL.getAttributeValues(FILTER_ATTR_SOURCE_IP);
boolean matches = values.isEmpty();
if (matches) {
// we got one!
break;
} else {
SocketAddress sourceAddress = receiver.getSourceAddress(uri);
InetAddress inetAddress;
if (sourceAddress instanceof InetSocketAddress) {
inetAddress = ((InetSocketAddress) sourceAddress).getAddress();
} else {
inetAddress = null;
}
int bestNetmask;
for (AttributeValue value : values) try {
if (! value.isString()) {
continue;
}
final String string = value.toString();
if (string.codePointAt(0) != '[') {
continue;
}
int closeBrace = string.indexOf(']', 1);
if (closeBrace == -1) {
continue;
}
final InetAddress matchAddress = InetAddress.getByName(string.substring(1, closeBrace));
if (string.codePointAt(closeBrace + 1) != '/') {
continue;
}
final int mask = Integer.parseInt(string.substring(closeBrace + 2));

// now do the test
if (inetAddress == null) {
if (mask == 0) {
// it's zero, so we can just break out now because we have the only match we're gonna get
break;
}
// else fall out because we have no source address to test
} else if (NetworkUtil.belongsToNetwork(inetAddress, matchAddress, mask)) {
// matched!
break;
}
} catch (RuntimeException ignored) {
// it's not a valid entry, so ignore it
}

// try again
}
}
}
final URI uri = serviceURL.getLocationURI();
final EJBReceiver receiver = getTransportProvider(uri.getScheme());
if (receiver != null) {
return locatedAction.execute(receiver, locator, Affinity.forUri(uri));
} else {
throw Logs.MAIN.noEJBReceiverAvailable(locator);
}
}

EJBClientInterceptor[] getInterceptors() {
return interceptors;
}

private static int getInt(byte[] b, int offs) {
return (b[offs] & 0xff) << 24 | (b[offs + 1] & 0xff) << 16 | (b[offs + 2] & 0xff) << 8 | b[offs + 3] & 0xff;
}

private static long getLong(byte[] b, int offs) {
return (getInt(b, offs) & 0xFFFFFFFFL) << 32 | getInt(b, offs + 4) & 0xFFFFFFFFL;
}

private static int nwsl(int arg, int places) {
return places <= 0 ? arg : places >= 32 ? 0 : arg << places;
}

private static long nwsl(long arg, int places) {
return places <= 0 ? arg : places >= 64 ? 0L : arg << places;
}
}
13 changes: 13 additions & 0 deletions src/main/java/org/jboss/ejb/client/EJBReceiver.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@

package org.jboss.ejb.client;

import java.net.SocketAddress;
import java.net.URI;

/**
* A receiver for EJB invocations. Receivers can be associated with one or more client contexts. This interface is
* implemented by providers for EJB invocation services.
Expand Down Expand Up @@ -71,4 +74,14 @@ protected boolean cancelInvocation(EJBReceiverInvocationContext receiverContext,
* session bean
*/
protected abstract <T> StatefulEJBLocator<T> createSession(final StatelessEJBLocator<T> statelessLocator) throws Exception;

/**
* Query the expected or actual source IP address configured for the given target URI.
*
* @param uri the supported URI of the peer (not {@code null})
* @return the socket address, or {@code null} if none is known
*/
protected SocketAddress getSourceAddress(final URI uri) {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.net.URI;
import java.net.URISyntaxException;

import org.jboss.ejb._private.NetworkUtil;
import org.xnio.OptionMap;
import org.xnio.Options;

Expand All @@ -47,7 +48,7 @@ static URI getUri(final JBossEJBProperties.ConnectionConfiguration connectionCon
protocol = "remote+http";
}
try {
return new URI(protocol, null, host, port, null, null, null);
return new URI(protocol, null, NetworkUtil.formatPossibleIpv6Address(host), port, null, null, null);
} catch (URISyntaxException e) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
import java.util.function.Consumer;

import org.jboss.ejb._private.Logs;
import org.jboss.ejb.client.ClusterNodeSelector;
import org.kohsuke.MetaInfServices;
import org.wildfly.common.function.ExceptionSupplier;
import org.wildfly.discovery.ServiceURL;
import org.wildfly.discovery.impl.StaticDiscoveryProvider;
import org.wildfly.discovery.spi.DiscoveryProvider;
Expand All @@ -49,7 +51,13 @@ public void configure(final Consumer<DiscoveryProvider> discoveryProviderConsume
for (Map.Entry<String, JBossEJBProperties.ClusterConfiguration> entry : ejbProperties.getClusterConfigurations().entrySet()) {
final String name = entry.getKey();
final JBossEJBProperties.ClusterConfiguration configuration = entry.getValue();
final ExceptionSupplier<ClusterNodeSelector, ReflectiveOperationException> clusterNodeSelectorSupplier = configuration.getClusterNodeSelectorSupplier();
final long maximumAllowedConnectedNodes = configuration.getMaximumAllowedConnectedNodes();

for (JBossEJBProperties.ClusterNodeConfiguration nodeConfiguration : configuration.getNodeConfigurations()) {
final String nodeName = nodeConfiguration.getNodeName();

}
// todo: construct URI and map cluster:name to it
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ public static void configure(final EJBClientContext.Builder builder) {
if (port == -1) {
continue;
}
final String protocol;
final OptionMap connectionOptions = connectionConfiguration.getConnectionOptions();
final URI uri = CommonLegacyConfiguration.getUri(connectionConfiguration, connectionOptions);
if (uri == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import java.util.List;

import org.jboss.ejb._private.Logs;
import org.jboss.remoting3.ConnectionBuilder;
import org.jboss.remoting3.Endpoint;
import org.jboss.remoting3.EndpointBuilder;
import org.jboss.remoting3.spi.EndpointConfigurator;
Expand Down Expand Up @@ -63,6 +62,12 @@ public Endpoint getConfiguredEndpoint() {

// we ignore the connection provider options

final Endpoint endpoint;
try {
endpoint = endpointBuilder.build();
} catch (IOException e) {
throw Logs.MAIN.failedToConstructEndpoint(e);
}
final List<JBossEJBProperties.ConnectionConfiguration> connectionList = properties.getConnectionList();
for (JBossEJBProperties.ConnectionConfiguration connectionConfiguration : connectionList) {
final OptionMap connectionOptions = connectionConfiguration.getConnectionOptions();
Expand All @@ -71,17 +76,10 @@ public Endpoint getConfiguredEndpoint() {
if (uri == null) {
continue;
}

final ConnectionBuilder connectionBuilder = endpointBuilder.addConnection(uri);
connectionBuilder.addAllOptions(connectionOptions);
connectionBuilder.setImmediate(connectionConfiguration.isConnectEagerly());
connectionBuilder.setAbstractType("ejb");
connectionBuilder.setAbstractTypeAuthority("jboss");
}
try {
return endpointBuilder.build();
} catch (IOException e) {
throw Logs.MAIN.failedToConstructEndpoint(e);
if (connectionConfiguration.isConnectEagerly()) {
endpoint.getConnection(uri, "ejb", "jboss");
}
}
return endpoint;
}
}
Loading

0 comments on commit c194ef5

Please sign in to comment.