GOSSIP-81 Move Jackson and UDP to their own modules
Part of what makes this work is the test implementation of TransportManager. This PR is pretty straightforward. A few gotchas though: * A message signing test was moved into `JacksonTests` because that is where the signing actually happens. * A CRDT serializing test was moved there as well. It's the best place for now. * No UDP tests at all. I plan to fix that in a bit. Reasoning is that it is difficult to test any TransportManager implementation without bring up a full stack. I plan to address this in the future (GOSSIP-83). * Simple round trip Jackson serialization tests.
This commit is contained in:
43
gossip-transport-udp/pom.xml
Normal file
43
gossip-transport-udp/pom.xml
Normal file
@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You 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
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.apache.gossip</groupId>
|
||||
<artifactId>gossip-parent</artifactId>
|
||||
<version>0.1.3-incubating-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>Gossip UDP Transport</name>
|
||||
<artifactId>gossip-transport-udp</artifactId>
|
||||
<version>0.1.3-incubating-SNAPSHOT</version>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.gossip</groupId>
|
||||
<artifactId>gossip-base</artifactId>
|
||||
<version>0.1.3-incubating-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.apache.gossip.transport.udp;
|
||||
|
||||
import org.apache.gossip.manager.GossipCore;
|
||||
import org.apache.gossip.manager.GossipManager;
|
||||
import org.apache.gossip.transport.AbstractTransportManager;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* This class is constructed by reflection in GossipManager.
|
||||
* It manages transport (byte read/write) operations over UDP.
|
||||
*/
|
||||
public class UdpTransportManager extends AbstractTransportManager {
|
||||
|
||||
public static final Logger LOGGER = Logger.getLogger(UdpTransportManager.class);
|
||||
|
||||
/** The socket used for the passive thread of the gossip service. */
|
||||
private final DatagramSocket server;
|
||||
|
||||
private final int soTimeout;
|
||||
|
||||
/** required for reflection to work! */
|
||||
public UdpTransportManager(GossipManager gossipManager, GossipCore gossipCore) {
|
||||
super(gossipManager, gossipCore);
|
||||
|
||||
soTimeout = gossipManager.getSettings().getGossipInterval() * 2;
|
||||
|
||||
try {
|
||||
SocketAddress socketAddress = new InetSocketAddress(gossipManager.getMyself().getUri().getHost(),
|
||||
gossipManager.getMyself().getUri().getPort());
|
||||
server = new DatagramSocket(socketAddress);
|
||||
} catch (SocketException ex) {
|
||||
LOGGER.warn(ex);
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
server.close();
|
||||
super.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* blocking read a message.
|
||||
* @return buffer of message contents.
|
||||
* @throws IOException
|
||||
*/
|
||||
public byte[] read() throws IOException {
|
||||
byte[] buf = new byte[server.getReceiveBufferSize()];
|
||||
DatagramPacket p = new DatagramPacket(buf, buf.length);
|
||||
server.receive(p);
|
||||
debug(p.getData());
|
||||
return p.getData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(URI endpoint, byte[] buf) throws IOException {
|
||||
DatagramSocket socket = new DatagramSocket();
|
||||
socket.setSoTimeout(soTimeout);
|
||||
InetAddress dest = InetAddress.getByName(endpoint.getHost());
|
||||
DatagramPacket payload = new DatagramPacket(buf, buf.length, dest, endpoint.getPort());
|
||||
socket.send(payload);
|
||||
// todo: investigate UDP socket reuse. It would save a little setup/teardown time wrt to the local socket.
|
||||
socket.close();
|
||||
}
|
||||
|
||||
private void debug(byte[] jsonBytes) {
|
||||
if (LOGGER.isDebugEnabled()){
|
||||
String receivedMessage = new String(jsonBytes);
|
||||
LOGGER.debug("Received message ( bytes): " + receivedMessage);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.apache.gossip.transport.udp;
|
||||
|
||||
import org.apache.gossip.GossipSettings;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class UdpTransportIntegrationTest {
|
||||
|
||||
// It's currently impossible to create a UdpTransportManager without bringing up an entire stack.
|
||||
// This is because AbstractTransportManager creates a PassiveGossipThread (requires GossipManager,
|
||||
// GossipCore) and also requires those same things plus a MetricsRegistry to create the
|
||||
// ActiveGossiper.
|
||||
// TODO: test UDPTransportManger semantics (read and write) in isolation.
|
||||
// I've written this test to indicate the direction I want things to go.
|
||||
// Uncomment/Fix it once the coupling issues are worked out.
|
||||
@Test @Ignore
|
||||
public void testRoundTrip() {
|
||||
/*
|
||||
GossipSettings settings0 = new GossipSettings();
|
||||
GossipSettings settings1 = new GossipSettings();
|
||||
UdpTransportManager mgr0 = new UdpTransportManager(settings0);
|
||||
UdpTransportManager mgr1 = new UdpTransportManager(settings1);
|
||||
|
||||
mgr0.startEndpoint();
|
||||
mgr1.startEndpoint();
|
||||
mgr0.startActiveGossiper();
|
||||
mgr1.startActiveGossiper();
|
||||
|
||||
// wait a little while for convergence
|
||||
// perhaps there is a Mockito Whitebox way to foce members
|
||||
|
||||
byte[] data = new byte[] {0,1,2,3,4,5};
|
||||
Future<byte[]> someData = asyncWaitForData(mgr1);
|
||||
mgr0.send(toURI(settings1), data);
|
||||
|
||||
Assert.assertEquals(data, someData.get(1000, TimeUnit.MILLISECONDS));
|
||||
|
||||
mgr0.shutdown();
|
||||
mgr1.shutdown();
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
}
|
Reference in New Issue
Block a user