docs: @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 /* Gone */).build();
                  } else {
                      log.debug("POST message {}: channel  unknown: {}", message, ccid);
                      return Response.status(404 /* Not Found */).build();
                  }
              }
  
              // if the receiver has never registered with the bounceproxy
              // (or his registration has expired) then return 204 no
              // 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);
          }
  
      }