use of io.joynr.communications.exceptions.JoynrHttpException in project joynr by bmwcarit.
the class LongPollingMessagingDelegate method postMessage.
/**
* Posts a message to a long polling channel.
*
* @param ccid
* the identifier of the long polling channel
* @param serializedMessage
* the message to send serialized as a SMRF message
* @return the path segment for the message status. The path, appended to
* the base URI of the messaging service, can be used to query the
* message status
*
* @throws JoynrHttpException
* if one of:
* <ul>
* <li>ccid is not set</li>
* <li>the message has expired or not expiry date is set</li>
* <li>no channel registered for ccid</li>
* </ul>
*/
public String postMessage(String ccid, byte[] serializedMessage) {
ImmutableMessage message;
try {
message = new ImmutableMessage(serializedMessage);
} catch (EncodingException | UnsuppportedVersionException e) {
throw new JoynrHttpException(Status.BAD_REQUEST, JOYNRMESSAGINGERROR_DESERIALIZATIONFAILED);
}
if (ccid == null) {
log.error("POST message {} to cluster controller: NULL. Dropped because: channel Id was not set.", message.getId());
throw new JoynrHttpException(Status.BAD_REQUEST, JOYNRMESSAGINGERROR_CHANNELNOTSET);
}
// send the message to the receiver.
if (message.getTtlMs() == 0) {
log.error("POST message {} to cluster controller: {} dropped because: expiry date not set", ccid, message.getId());
throw new JoynrHttpException(Status.BAD_REQUEST, JOYNRMESSAGINGERROR_EXPIRYDATENOTSET);
}
// Relative TTLs are not supported yet.
if (!message.isTtlAbsolute()) {
throw new JoynrHttpException(Status.BAD_REQUEST, JOYNRMESSAGINGERROR_RELATIVE_TTL_UNSPORTED);
}
if (message.getTtlMs() < System.currentTimeMillis()) {
log.warn("POST message {} to cluster controller: {} dropped because: TTL expired", ccid, message.getId());
throw new JoynrHttpException(Status.BAD_REQUEST, JOYNRMESSAGINGERROR_EXPIRYDATEEXPIRED);
}
// look for an existing broadcaster
Broadcaster ccBroadcaster = BroadcasterFactory.getDefault().lookup(Broadcaster.class, ccid, false);
if (ccBroadcaster == null) {
// if the receiver has never registered with the bounceproxy
// (or his registration has expired) then return 204 no
// content.
log.error("POST message {} to cluster controller: {} dropped because: no channel found", ccid, message.getId());
throw new JoynrHttpException(Status.BAD_REQUEST, JOYNRMESSAGINGERROR_CHANNELNOTFOUND);
}
if (ccBroadcaster.getAtmosphereResources().size() == 0) {
log.debug("no poll currently waiting for channelId: {}", ccid);
}
ccBroadcaster.broadcast(message);
return "messages/" + message.getId();
}
use of io.joynr.communications.exceptions.JoynrHttpException in project joynr by bmwcarit.
the class JeeMessagingEndpoint method postMessage.
/**
* Receives a binary encoded {@link ImmutableMessage} which it then routes to the {@link #messageReceiver message
* receiver} in the joynr runtime.
*
* @param channelId
* channel id of the receiver.
* @param serializedMessage
* a serialized SMRF message being sent.
* @param uriInfo
* the URI Information for the request being processed.
* @return a location for querying the message status.
*/
@POST
@Path("/{channelId: [A-Z,a-z,0-9,_,\\-,\\.]+}/message")
@Produces({ MediaType.APPLICATION_OCTET_STREAM })
public Response postMessage(@PathParam("channelId") String channelId, byte[] serializedMessage, @Context UriInfo uriInfo) {
if (LOG.isDebugEnabled()) {
LOG.debug("Incoming message:\n" + new String(serializedMessage, Charsets.UTF_8));
}
try {
ImmutableMessage message;
try {
message = new ImmutableMessage(serializedMessage);
} catch (EncodingException | UnsuppportedVersionException exception) {
LOG.error("Failed to deserialize message for channelId {}: {}", channelId, exception.getMessage());
throw new JoynrHttpException(Status.BAD_REQUEST, JOYNRMESSAGINGERROR_DESERIALIZATIONFAILED);
}
if (LOG.isDebugEnabled()) {
LOG.debug("POST to channel: {} message: {}", channelId, message);
}
if (channelId == null) {
LOG.error("POST message to channel: NULL. message: {} dropped because: channel Id was not set", message);
throw new JoynrHttpException(Status.BAD_REQUEST, JOYNRMESSAGINGERROR_CHANNELNOTSET);
}
if (message.getTtlMs() == 0) {
LOG.error("POST message to channel: {} message: {} dropped because: TTL not set", channelId, message);
throw new JoynrHttpException(Status.BAD_REQUEST, JOYNRMESSAGINGERROR_EXPIRYDATENOTSET);
}
if (messageReceiver == null) {
LOG.error("POST message to channel: {} message: {} no receiver for the given channel", channelId, message);
return Response.noContent().build();
}
if (LOG.isTraceEnabled()) {
LOG.trace("passing off message to messageReceiver: {}", channelId);
}
messageReceiver.receive(message);
URI location = uriInfo.getBaseUriBuilder().path("messages/" + message.getId()).build();
return Response.created(location).build();
} catch (WebApplicationException e) {
throw e;
} catch (Exception e) {
LOG.error(format("POST message to channel: %s error: %s", channelId, e.getMessage()), e);
throw new WebApplicationException(Status.INTERNAL_SERVER_ERROR);
}
}
use of io.joynr.communications.exceptions.JoynrHttpException in project joynr by bmwcarit.
the class MessagingServiceRestAdapter method postMessage.
/**
* Send a message.
*
* @param ccid
* channel id of the receiver.
* @param message
* the content being sent (serialized SMRF message).
* @return a location for querying the message status
*/
@POST
@Produces({ MediaType.APPLICATION_OCTET_STREAM })
public Response postMessage(@PathParam("ccid") String ccid, byte[] serializedMessage) {
ImmutableMessage message;
try {
message = new ImmutableMessage(serializedMessage);
} catch (EncodingException | UnsuppportedVersionException e) {
throw new JoynrHttpException(Status.BAD_REQUEST, JOYNRMESSAGINGERROR_DESERIALIZATIONFAILED);
}
try {
log.debug("POST message to channel: {} message: {}", ccid, message);
// TODO Can this happen at all with empty path parameter???
if (ccid == null) {
log.error("POST message to channel: NULL. message: {} dropped because: channel Id was not set", message);
throw new JoynrHttpException(Status.BAD_REQUEST, JOYNRMESSAGINGERROR_CHANNELNOTSET);
}
// send the message to the receiver.
if (message.getTtlMs() == 0) {
log.error("POST message to channel: {} message: {} dropped because: TTL not set", ccid, message);
throw new JoynrHttpException(Status.BAD_REQUEST, JOYNRMESSAGINGERROR_EXPIRYDATENOTSET);
}
if (message.getTtlMs() < timestampProvider.getCurrentTime()) {
log.warn("POST message {} to cluster controller: {} dropped because: TTL expired", ccid, message.getId());
throw new JoynrHttpException(Status.BAD_REQUEST, JOYNRMESSAGINGERROR_EXPIRYDATEEXPIRED, request.getRemoteHost());
}
if (!messagingService.isAssignedForChannel(ccid)) {
// scalability extensions: in case that other component should handle this channel
log.debug("POST message {}: Bounce Proxy not assigned for channel: {}", message, ccid);
if (messagingService.hasChannelAssignmentMoved(ccid)) {
// scalability extension: in case that this component was responsible before but isn't any more
log.debug("POST message {}: Bounce Proxy assignment moved for channel: {}", message, ccid);
return Response.status(410).build();
} else {
log.debug("POST message {}: channel unknown: {}", message, ccid);
return Response.status(404).build();
}
}
// content.
if (!messagingService.hasMessageReceiver(ccid)) {
log.debug("POST message {}: no receiver for channel: {}", message, ccid);
return Response.noContent().build();
}
messagingService.passMessageToReceiver(ccid, serializedMessage);
// the location that can be queried to get the message
// status
// TODO REST URL for message status?
URI location = ui.getBaseUriBuilder().path("messages/" + message.getId()).build();
// encode URL in case we use sessions
String encodeURL = response.encodeURL(location.toString());
// return the message status location to the sender.
return Response.created(URI.create(encodeURL)).header("msgId", message.getId()).build();
} catch (WebApplicationException e) {
throw e;
} catch (Exception e) {
log.debug("POST message to channel: {} error: {}", ccid, e.getMessage());
throw new WebApplicationException(e, Status.INTERNAL_SERVER_ERROR);
}
}
use of io.joynr.communications.exceptions.JoynrHttpException in project joynr by bmwcarit.
the class ChannelServiceRestAdapter method createChannel.
/**
* HTTP POST to create a channel, returns location to new resource which can
* then be long polled. Since the channel id may later change to be a UUID,
* not using a PUT but rather POST with used id being returned
* @param ccid cluster controller id
* @param atmosphereTrackingId tracking id for atmosphere
* @return location to new resource
*/
@POST
@Produces({ MediaType.TEXT_PLAIN })
public Response createChannel(@QueryParam("ccid") String ccid, @HeaderParam(ChannelServiceConstants.X_ATMOSPHERE_TRACKING_ID) String atmosphereTrackingId) {
try {
log.info("CREATE channel for channel ID: {}", ccid);
if (ccid == null || ccid.isEmpty())
throw new JoynrHttpException(Status.BAD_REQUEST, JOYNRMESSAGINGERROR_CHANNELNOTSET);
Channel channel = channelService.getChannel(ccid);
if (channel != null) {
String encodedChannelLocation = response.encodeURL(channel.getLocation().toString());
return Response.ok().entity(encodedChannelLocation).header("Location", encodedChannelLocation).header("bp", channel.getBounceProxy().getId()).build();
}
// look for an existing bounce proxy handling the channel
channel = channelService.createChannel(ccid, atmosphereTrackingId);
String encodedChannelLocation = response.encodeURL(channel.getLocation().toString());
log.debug("encoded channel URL " + channel.getLocation() + " to " + encodedChannelLocation);
return Response.created(URI.create(encodedChannelLocation)).entity(encodedChannelLocation).header("bp", channel.getBounceProxy().getId()).build();
} catch (WebApplicationException ex) {
throw ex;
} catch (Exception e) {
throw new WebApplicationException(e);
}
}
use of io.joynr.communications.exceptions.JoynrHttpException in project joynr by bmwcarit.
the class LongPollingMessagingDelegate method createChannel.
/**
* Creates a long polling channel.
*
* @param ccid
* the identifier of the channel
* @param atmosphereTrackingId
* the tracking ID of the channel
* @return the path segment for the channel. The path, appended to the base
* URI of the channel service, can be used to post messages to the
* channel.
*/
public String createChannel(String ccid, String atmosphereTrackingId) {
throwExceptionIfTrackingIdnotSet(atmosphereTrackingId);
log.info("CREATE channel for cluster controller: {} trackingId: {} ", ccid, atmosphereTrackingId);
Broadcaster broadcaster = null;
// look for an existing broadcaster
BroadcasterFactory defaultBroadcasterFactory = BroadcasterFactory.getDefault();
if (defaultBroadcasterFactory == null) {
throw new JoynrHttpException(500, 10009, "broadcaster was null");
}
broadcaster = defaultBroadcasterFactory.lookup(Broadcaster.class, ccid, false);
// create a new one if none already exists
if (broadcaster == null) {
broadcaster = defaultBroadcasterFactory.get(BounceProxyBroadcaster.class, ccid);
}
// especially as seen in js, where every second refresh caused a fail
for (AtmosphereResource resource : broadcaster.getAtmosphereResources()) {
if (resource.uuid() != null && resource.uuid().equals(atmosphereTrackingId)) {
resource.resume();
}
}
UUIDBroadcasterCache broadcasterCache = (UUIDBroadcasterCache) broadcaster.getBroadcasterConfig().getBroadcasterCache();
broadcasterCache.activeClients().put(atmosphereTrackingId, System.currentTimeMillis());
return "/channels/" + ccid + "/";
}
Aggregations