Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement TCPServerCommProvider #241

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,41 +1,53 @@
/***************************** BEGIN LICENSE BLOCK ***************************

The contents of this file are subject to the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one
at http://mozilla.org/MPL/2.0/.

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the License.

Copyright (C) 2012-2015 Sensia Software LLC. All Rights Reserved.

******************************* END LICENSE BLOCK ***************************/
The contents of this file are subject to the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one
at http://mozilla.org/MPL/2.0/.

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the License.

Copyright (C) 2012-2023 Sensia Software LLC. and Botts Innovative Research, Inc. All Rights Reserved.
******************************* END LICENSE BLOCK ***************************/

package org.sensorhub.api.comm;

import org.sensorhub.api.module.IModule;
import org.sensorhub.impl.comm.ConnectionEventArgs;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.sensorhub.api.module.IModule;

import java.util.function.Consumer;

/**
* <p>
* Interface for all communication providers giving access to an input stream
* for reading incoming data and an output stream for sending outgoing data.
* </p>
*
* @author Alex Robin
* @param <ConfigType> Comm module config type
* @author Alex Robin
* @since Jun 19, 2015
*/
public interface ICommProvider<ConfigType extends CommProviderConfig<?>> extends IModule<ConfigType>
{

public InputStream getInputStream() throws IOException;


public OutputStream getOutputStream() throws IOException;

public interface ICommProvider<ConfigType extends CommProviderConfig<?>> extends IModule<ConfigType> {

InputStream getInputStream() throws IOException;


OutputStream getOutputStream() throws IOException;

/**
* Adds a connection event handler to this comm provider.
* The handler will be called when a connection is established.
* <p>
* For client comm providers, this will be called when the comm module starts.
* Make sure to register the handler before starting the module or the event will be missed.
* <p>
* For server comm providers, this will be called every time a client connects.
*
* @param eventHandler The event handler to add
*/
void onConnection(Consumer<ConnectionEventArgs> eventHandler);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/***************************** BEGIN LICENSE BLOCK ***************************
The contents of this file are subject to the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one
at http://mozilla.org/MPL/2.0/.

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the License.

Copyright (C) 2023 Botts Innovative Research Inc. All Rights Reserved.
******************************* END LICENSE BLOCK ***************************/

package org.sensorhub.impl.comm;

import java.io.InputStream;
import java.io.OutputStream;

/**
* Event arguments for a connection event
*
* @author Michael Elmore
* @since September 2023
*/
public class ConnectionEventArgs {
private final InputStream inputStream;
private final OutputStream outputStream;

/**
* @param inputStream The input stream for the connection
* @param outputStream The output stream for the connection
*/
public ConnectionEventArgs(InputStream inputStream, OutputStream outputStream) {
this.inputStream = inputStream;
this.outputStream = outputStream;
}

/**
* @return The input stream for the connection
*/
public InputStream getInputStream() {
return inputStream;
}

/**
* @return The output stream for the connection
*/
public OutputStream getOutputStream() {
return outputStream;
}
}
Original file line number Diff line number Diff line change
@@ -1,33 +1,36 @@
/***************************** BEGIN LICENSE BLOCK ***************************

The contents of this file are subject to the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one
at http://mozilla.org/MPL/2.0/.

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the License.

Copyright (C) 2012-2015 Sensia Software LLC. All Rights Reserved.

******************************* END LICENSE BLOCK ***************************/
The contents of this file are subject to the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one
at http://mozilla.org/MPL/2.0/.

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the License.

Copyright (C) 2012-2023 Sensia Software LLC. and Botts Innovative Research, Inc. All Rights Reserved.
******************************* END LICENSE BLOCK ***************************/

package org.sensorhub.impl.comm;

import org.sensorhub.api.comm.ICommProvider;
import org.sensorhub.api.common.SensorHubException;
import org.sensorhub.impl.module.AbstractModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import org.sensorhub.api.comm.ICommProvider;
import org.sensorhub.api.common.SensorHubException;
import org.sensorhub.impl.module.AbstractModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Consumer;


/**
Expand All @@ -38,84 +41,79 @@
* @author Alex Robin
* @since July 2, 2015
*/
public class TCPCommProvider extends AbstractModule<TCPCommProviderConfig> implements ICommProvider<TCPCommProviderConfig>
{
public class TCPCommProvider extends AbstractModule<TCPCommProviderConfig> implements ICommProvider<TCPCommProviderConfig> {
static final Logger log = LoggerFactory.getLogger(TCPCommProvider.class.getSimpleName());

private final Set<Consumer<ConnectionEventArgs>> listeners = new HashSet<>();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 Questions:

  1. Why a Set<> and why not just a simple ArrayList<>?
  2. There should be a single commProvider per "driver" and a single "Consumer" pre comm provider shouldn't there? Maybe I am not thinking about this right but what is the use case for 1 CommProvider to multiple listeners?


Socket socket;
InputStream is;
OutputStream os;


public TCPCommProvider()
{


public TCPCommProvider() {
}


@Override
public InputStream getInputStream() throws IOException
{
public InputStream getInputStream() throws IOException {
return is;
}


@Override
public OutputStream getOutputStream() throws IOException
{
public OutputStream getOutputStream() throws IOException {
return os;
}


@Override
protected void doStart() throws SensorHubException
{
protected void doStart() throws SensorHubException {
TCPConfig config = this.config.protocol;

try
{

try {
InetAddress addr = InetAddress.getByName(config.remoteHost);

if (config.enableTLS)
{
SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.getDefault();

if (config.enableTLS) {
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
socket = factory.createSocket(addr, config.remotePort);
((SSLSocket)socket).startHandshake();
is = socket.getInputStream();
os = socket.getOutputStream();
}
else
{
((SSLSocket) socket).startHandshake();
} else {
SocketAddress endpoint = new InetSocketAddress(addr, config.remotePort);
socket = new Socket();
socket.connect(endpoint, 1000);
is = socket.getInputStream();
os = socket.getOutputStream();
}
}
catch (IOException e)
{

is = socket.getInputStream();
os = socket.getOutputStream();
broadcast(is, os);
} catch (IOException e) {
throw new SensorHubException("Cannot connect to remote host "
+ config.remoteHost + ":" + config.remotePort + " via TCP", e);
+ config.remoteHost + ":" + config.remotePort + " via TCP", e);
}
}


@Override
protected void doStop() throws SensorHubException
{
try
{
protected void doStop() throws SensorHubException {
try {
socket.close();
}
catch (IOException e)
{
} catch (IOException e) {
log.trace("Cannot close socket", e);
}
}
}


@Override
public void cleanup() throws SensorHubException
{
public void cleanup() throws SensorHubException {
}

@Override
public void onConnection(Consumer<ConnectionEventArgs> eventHandler) {
listeners.add(eventHandler);
}

private void broadcast(InputStream input, OutputStream output) {
var args = new ConnectionEventArgs(input, output);
listeners.forEach(listener -> listener.accept(args));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/***************************** BEGIN LICENSE BLOCK ***************************
The contents of this file are subject to the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one
at http://mozilla.org/MPL/2.0/.

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the License.

Copyright (C) 2023 Botts Innovative Research Inc. All Rights Reserved.
******************************* END LICENSE BLOCK ***************************/

package org.sensorhub.impl.comm;

import org.sensorhub.api.module.IModule;
import org.sensorhub.api.module.IModuleProvider;
import org.sensorhub.api.module.ModuleConfig;
import org.sensorhub.impl.module.JarModuleProvider;

/**
* Communication provider for TCP/IP server connections.
*
* @author Michael Elmore
* @since September 2023
*/
public class TCPServerCommModuleDescriptor extends JarModuleProvider implements IModuleProvider {
@Override
public String getModuleName() {
return "TCP Server Comm Driver";
}

@Override
public String getModuleDescription() {
return "Simple TCP/IP server communication provider using JDK TCP stack";
}

@Override
public Class<? extends IModule<?>> getModuleClass() {
return TCPServerCommProvider.class;
}

@Override
public Class<? extends ModuleConfig> getModuleConfigClass() {
return TCPServerCommProviderConfig.class;
}
}
Loading
Loading