@Override
  public void onReceive(ActorRef httpService, HttpRequest message) throws Exception {
    ApiHttpMessage apiMessage = ApiHttpMessage.parse(message);
    if (apiMessage == null) {
      log.warn(String.format("Invalid url path[%s]", message.getUrl()));
      sendHttpResponse(httpService, HttpResponseStatus.BAD_REQUEST, null);
      return;
    }

    // double check domain
    if (!apiMessage.getDomain().toLowerCase().startsWith("user")) {
      log.warn(
          String.format("Not registered for this controller[%s != user]", apiMessage.getDomain()));
      sendHttpResponse(httpService, HttpResponseStatus.BAD_REQUEST, null);
      return;
    }
    if (log.isDebugEnabled()) {
      log.debug(String.format("%s %s", apiMessage.getActorId(), apiMessage.getMethod()));
    }

    // create / update user ?
    ActorRef user = null;
    if (HttpMethod.POST == apiMessage.getMethod()) {
      user = createActor(httpService, apiMessage);
      if (user == null) {
        // user not created, whilst it should. Response have been sent
        return;
      }
    } else {
      user = getSystem().actorFor(String.format("user/%s", apiMessage.getActorId()));
    }

    if (HttpMethod.DELETE == apiMessage.getMethod()) {
      if (ApiConfig.checkForExistenceBeforeDelete()) {
        user.tell(apiMessage, httpService);
      } else {
        // remove user directly (without checking if it exist)
        getSystem().stop(user);
        sendHttpResponse(httpService, HttpResponseStatus.OK, null);
      }
    } else {
      // ok, dispatch message to user, but use httpService as sender, since the onUndelivered
      // doesn't have a handle to the temporarily httpResponseActor
      user.tell(apiMessage, httpService);
    }
  }
  private ActorRef createActor(ActorRef httpService, ApiHttpMessage message) {

    if (!message.hasContent()) {
      sendHttpResponse(httpService, HttpResponseStatus.NO_CONTENT, null);
      return null;
    }
    if (message.getMethod() != HttpMethod.POST) {
      sendHttpResponse(httpService, HttpResponseStatus.NOT_ACCEPTABLE, "Post method required");
      return null;
    }
    if (!message.hasJsonContentType()) {
      sendHttpResponse(httpService, HttpResponseStatus.NOT_ACCEPTABLE, "No JSon content type");
      return null;
    }
    User.State state = message.getContent(User.State.class);
    if (state == null) {
      sendHttpResponse(
          httpService, HttpResponseStatus.NOT_ACCEPTABLE, "JSon content not of type User.State");
      return null;
    }

    // uid
    String uid = state.getUsername();
    if (!StringUtils.hasLength(uid)) {
      sendHttpResponse(
          httpService, HttpResponseStatus.NOT_ACCEPTABLE, "No username found in User.State");
      return null;
    }
    if (StringUtils.hasLength(message.getActorId()) && !uid.equals(message.getActorId())) {
      log.warn(
          String.format(
              "Username of state[%s] does not equal the UID found in url[%s]. " + "Using [%s]",
              uid, message.getActorId(), uid));
    }
    try {
      return getSystem().actorOf(String.format("user/%s", uid), User.class, state);
    } catch (Exception e) {
      log.error(e.getMessage(), e);
      sendHttpResponse(httpService, HttpResponseStatus.INTERNAL_SERVER_ERROR, e.getMessage());
    }
    return null;
  }