/**
* Copyright 2015-2017 Linagora, Université Joseph Fourier, Floralis
*
* The present code is developed in the scope of the joint LINAGORA -
* Université Joseph Fourier - Floralis research program and is designated
* as a "Result" pursuant to the terms and conditions of the LINAGORA
* - Université Joseph Fourier - Floralis research program. Each copyright
* holder of Results enumerated here above fully & independently holds complete
* ownership of the complete Intellectual Property rights applicable to the whole
* of said Results, and may freely exploit it in any manner which does not infringe
* the moral rights of the other copyright holders.
*
* 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
*
* 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 net.roboconf.messaging.http.internal;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.logging.Logger;
import org.eclipse.jetty.websocket.api.RemoteEndpoint;
import net.roboconf.messaging.api.MessagingConstants;
import net.roboconf.messaging.api.messages.Message;
import net.roboconf.messaging.api.utils.SerializationUtils;
import net.roboconf.messaging.http.HttpConstants;
/**
* @author Vincent Zurczak - Linagora
*/
public final class HttpUtils {
/**
* Private empty constructor.
*/
private HttpUtils() {
// nothing
}
/**
* Return a HTTP messaging configuration for the given parameters.
* @param agentPort the HTTP server port of the agent.. May be {@code null}.
* @return the messaging configuration for the given parameters.
*/
public static Map<String,String> httpMessagingConfiguration( String ip, int port ) {
final Map<String,String> result = new LinkedHashMap<>();
result.put( MessagingConstants.MESSAGING_TYPE_PROPERTY, HttpConstants.FACTORY_HTTP );
result.put( HttpConstants.HTTP_SERVER_IP, ip == null ? HttpConstants.DEFAULT_IP : ip );
result.put( HttpConstants.HTTP_SERVER_PORT, "" + (port <= 0 ? HttpConstants.DEFAULT_PORT : port));
return result;
}
/**
* Sends a message asynchronously to a remote end point.
* <p>
* Asynchronous sending is necessary since we may have several threads that
* use the same messaging client. Blocking sending may result in issues such
* as #598.
* </p>
*
* @param message the message to send
* @param remoteEndpoint the remote end-point
* @throws IOException if something went wrong
*/
public static void sendAsynchronously( Message message, RemoteEndpoint remoteEndpoint )
throws IOException {
Future<Void> fut = null;
Exception exception = null;
try {
byte[] rawData = SerializationUtils.serializeObject( message );
ByteBuffer data = ByteBuffer.wrap( rawData );
fut = remoteEndpoint.sendBytesByFuture( data );
// Wait for completion (timeout)
fut.get( 8, TimeUnit.SECONDS );
} catch( ExecutionException | InterruptedException e ) {
exception = e;
} catch( TimeoutException e ) {
exception = e;
final Logger logger = Logger.getLogger( HttpUtils.class.getName());
logger.warning( "A message could not be sent to a remote end-point (HTTP messaging). Sending timed out." );
// FIXME: should we send the message once again?
if( fut != null )
fut.cancel(true);
} finally {
if( exception != null )
throw new IOException( exception );
}
}
}