示例#1
0
void api_respond_error(msgpack_object *request_obj,
                       msgpack_packer *response_msg, const char *error) {
  msgpack_pack_map(response_msg, 2);
  msgpack_pack_string(response_msg, "error", -1);
  msgpack_pack_string(response_msg, error, -1);
  msgpack_pack_string(response_msg, "request", -1);
  msgpack_pack_object(response_msg, *request_obj);
} 
示例#2
0
/**
 * plume_req_init_route - Initialize a route request, additionally packing our
 * peer's handle and an opcode for our peer.
 */
void
plume_req_init_route(struct yakyak *yy, struct plume_client *client, char *op,
    char *peer_handle, unsigned n)
{
  plume_req_init(yy, client, "route", n + 2);

  msgpack_pack_string(yy->pk, peer_handle);
  msgpack_pack_string(yy->pk, op);
}
示例#3
0
void api_request_dance(rpc_io *rpcio, msgpack_object *request,
                       msgpack_packer *response_msg) {
  printf("Dance dance dance. La la la.\n");

  msgpack_pack_map(response_msg, 1);
  msgpack_pack_string(response_msg, "danced", 6);
  msgpack_pack_true(response_msg);
}
示例#4
0
void rpc_m_list_methods(void *context, msgpack_object *request,
                        msgpack_packer *result, msgpack_packer *error,
                        void *data) {

  //msgpack_pack_array(result, 1);
  msgpack_pack_string(result, "danced", 6);
  msgpack_pack_nil(error);
} /* rpc_m_list_methods */
示例#5
0
/**
 * plume_req_route_connect - Send a peer our calling card.
 */
int
plume_req_route_connect(struct plume_client *client, char *peer_handle)
{
  struct yakyak yy;

  plume_req_init_route(&yy, client, "connect", peer_handle, 1);
  msgpack_pack_string(yy.pk, "callingcard");

  return plume_send(client, yakyak_data(&yy), yakyak_size(&yy));
}
示例#6
0
void
dump_oid_info(msgpack_packer *pk, struct oid_info *oi)
{
	#define DUMPi(field) msgpack_pack_named_int(pk, #field, oi->field)
	msgpack_pack_map(pk, 6);

	DUMPi(sid);
	DUMPi(cid);
	DUMPi(fd);
	DUMPi(max_repetitions);
	msgpack_pack_string(pk, "oid");
	msgpack_pack_oid(pk, oi->oid);
	msgpack_pack_string(pk, "value");
	if (!oi->value.buf)
		msgpack_pack_nil(pk);
	else
		msgpack_pack_ber(pk, oi->value);

	#undef DUMPi
}
示例#7
0
/**
 * plume_req_init - Initialize a yakyak, then pack an opcode and our cert.
 */
void
plume_req_init(struct yakyak *yy, struct plume_client *client, char *op,
    unsigned n)
{
  yakyak_init(yy, 2);

  msgpack_pack_string(yy->pk, op);
  msgpack_pack_array(yy->pk, n + 1);
  msgpack_pack_raw(yy->pk, client->pc_cert_size);
  msgpack_pack_raw_body(yy->pk, client->pc_cert, client->pc_cert_size);
}
示例#8
0
void publish_output(process_t *process, struct proc_data *procdata,
                    const char *ioname, const char *data, ssize_t length) {
  /* TODO(sissel): move this to a separate file for 'event' streaming */
  zmq_msg_t event;
  int rc;
  size_t msgsize;
  program_t *program = pn_proc_program(process);
  procnanny_t *pn = program->data;

  fprintf(stdout, "%s[%d]: (%d bytes) %.*s\n", pn_proc_program(process)->name,
          pn_proc_instance(process), length, length, data);

  /* Fields:
   *  - data (the string read)
   *  - program name
   *  - process instance
   *  - stdout or stderr
   */

  msgpack_sbuffer *buffer = msgpack_sbuffer_new();
  msgpack_packer *output_msg = msgpack_packer_new(buffer, msgpack_sbuffer_write);

  msgpack_pack_map(output_msg, 5);

  /* "event" => "data" */
  msgpack_pack_string(output_msg, "event", -1);
  msgpack_pack_string(output_msg, "data", -1);

  msgpack_pack_string(output_msg, "program", -1);
  msgpack_pack_string(output_msg, program->name, program->name_len);

  msgpack_pack_string(output_msg, "instance", -1);
  msgpack_pack_int(output_msg, process->instance);

  msgpack_pack_string(output_msg, "source", -1);
  msgpack_pack_string(output_msg, ioname, -1);

  msgpack_pack_string(output_msg, "data", -1);
  msgpack_pack_string(output_msg, data, length);

  zmq_msg_init_data(&event, buffer->data, buffer->size, free_msgpack_buffer, buffer); 
  zmq_send(pn->eventsocket, &event, 0);
  zmq_msg_close(&event);

  msgpack_packer_free(output_msg);
} /* publish_output */
示例#9
0
文件: rpc.c 项目: 40a/experiments
rpc_call_t *rpc_call_new(void *zmq, struct ev_loop *ev, const char *address,
                         const char *method) {
  rpc_call_t *rpc = calloc(1, sizeof(rpc_call_t));
  rpc->zmq = zmq;
  rpc->ev = ev;
  rpc->address = address;

  rpc->pack_buffer = msgpack_sbuffer_new();
  rpc->request = msgpack_packer_new(rpc->pack_buffer, msgpack_sbuffer_write);

  msgpack_pack_map(rpc->request, 2); /* method and args */
  msgpack_pack_string(rpc->request, "method", 6);
  msgpack_pack_string(rpc->request, method, strlen(method));
  msgpack_pack_string(rpc->request, "args", 4);

  /* The rest of the packing is up to the invoker of the rpc call.
   * Add whatever arguments are necessary later to rpc->request */

  printf("Created new rpc call object targeting %s method %s\n",
         address, method);
  return rpc;
} /* rpc_call_new */
示例#10
0
文件: util.c 项目: GrayHatter/toxcore
int msgpack_pack_vstringf(msgpack_packer *pk, char const *fmt, va_list ap)
{
    char buf[1024];
    vsnprintf(buf, sizeof buf, fmt, ap);
    return msgpack_pack_string(pk, buf);
}
示例#11
0
void api_request_status(rpc_io *rpcio, msgpack_object *request_obj,
                        msgpack_packer *response_msg) {
  int rc;
  char *program_name = NULL;
  size_t program_len = 0;
  rc = obj_get(request_obj, "program", MSGPACK_OBJECT_RAW, &program_name, &program_len);
  /* A missing 'program' field is OK. It means we want all programs */

  msgpack_pack_map(response_msg, 1);
  msgpack_pack_string(response_msg, "programs", -1);

  /* programs is a map of:
   *   programname => {
   *     command: "string",
   *     args: "string",
   *     uid: uid,
   *     gid: gid,
   *     nice: nice,
   *     ionice: ionice,
   *     is_running: boolean
   *     instances: {
   *       pid: ...
   *       state: ...
   *       admin_state: ...
   *       start: ...
   *       duration: ...
   *     }
   *   }
   */
  msgpack_pack_map(response_msg, rpcio->procnanny->programs_len);

  pn_prog_each(rpcio->procnanny, i, program, {
    if (program_name != NULL && strncmp(program->name, program_name, program_len)) {
      continue;
    }

    msgpack_pack_string(response_msg, program->name, program->name_len);
    msgpack_pack_map(response_msg, 8);  /* 8 fields */

    msgpack_pack_string(response_msg, "command", -1);
    msgpack_pack_string(response_msg, program->command, program->command_len);

    msgpack_pack_string(response_msg, "args", -1);
    msgpack_pack_array(response_msg, program->args_len);
    int argind = 0;
    for (argind = 0; argind < program->args_len; argind++) {
      msgpack_pack_string(response_msg, program->args[argind], -1);
    }

    msgpack_pack_string(response_msg, "uid", -1);
    msgpack_pack_uint32(response_msg, program->uid);

    msgpack_pack_string(response_msg, "gid", -1);
    msgpack_pack_uint32(response_msg, program->gid);

    msgpack_pack_string(response_msg, "nice", -1);
    msgpack_pack_int32(response_msg, program->nice);

    msgpack_pack_string(response_msg, "ionice", -1);
    msgpack_pack_int32(response_msg, program->ionice);

    msgpack_pack_string(response_msg, "active", -1);
    msgpack_pack_true(response_msg);

    msgpack_pack_string(response_msg, "instances", -1);
    msgpack_pack_map(response_msg, program->nprocs);

    pn_prog_proc_each(program, instance, process, {
      msgpack_pack_uint32(response_msg, instance);
      msgpack_pack_map(response_msg, 5);

      msgpack_pack_string(response_msg, "pid", -1);
      msgpack_pack_uint32(response_msg, process->pid);

      msgpack_pack_string(response_msg, "state", -1);
      switch (process->state) {
        case PROCESS_STATE_STARTING:
          msgpack_pack_string(response_msg, "starting", -1); break;
        case PROCESS_STATE_RUNNING:
          msgpack_pack_string(response_msg, "running", -1); break;
        case PROCESS_STATE_STOPPING:
          msgpack_pack_string(response_msg, "stopping", -1); break;
        case PROCESS_STATE_EXITED:
          msgpack_pack_string(response_msg, "exited", -1); break;
        case PROCESS_STATE_BACKOFF:
          msgpack_pack_string(response_msg, "backoff", -1); break;
        case PROCESS_STATE_NEW:
          msgpack_pack_string(response_msg, "new", -1); break;
        default:
          msgpack_pack_string(response_msg, "unknown", -1); break;
      }

      msgpack_pack_string(response_msg, "exitcode", -1);
      msgpack_pack_uint8(response_msg, process->exit_status);

      msgpack_pack_string(response_msg, "exitsignal", -1);
      msgpack_pack_uint8(response_msg, process->exit_signal);

      msgpack_pack_string(response_msg, "admin_state", -1);
      switch (process->admin_state) {
        case ADMIN_STATE_DOWN:
          msgpack_pack_string(response_msg, "down", -1); break;
        case ADMIN_STATE_UP:
          msgpack_pack_string(response_msg, "up", -1); break;
        default:
          msgpack_pack_string(response_msg, "unknown", -1); break;
      }
    })
  });
示例#12
0
void publish_proc_event(process_t *process, const char *name) {
  /* TODO(sissel): move this to a separate file for 'event' streaming */
  zmq_msg_t event;
  int rc;
  size_t msgsize;
  program_t *program = pn_proc_program(process);
  procnanny_t *pn = program->data;

  /* Fields:
   *  - program name
   *  - process instance
   *  - exit status
   *  - duration ?
   */

  msgpack_sbuffer *buffer = msgpack_sbuffer_new();
  msgpack_packer *output_msg = msgpack_packer_new(buffer, msgpack_sbuffer_write);

  msgpack_pack_map(output_msg, 5);
  msgpack_pack_string(output_msg, "event", -1);
  msgpack_pack_string(output_msg, name, -1);

  msgpack_pack_string(output_msg, "program", -1);
  msgpack_pack_string(output_msg, program->name, program->name_len);

  msgpack_pack_string(output_msg, "instance", -1);
  msgpack_pack_int(output_msg, process->instance);

  msgpack_pack_string(output_msg, "state", -1);
  switch (process->state) {
    case PROCESS_STATE_STARTING: msgpack_pack_string(output_msg, "starting", -1); break;
    case PROCESS_STATE_RUNNING: msgpack_pack_string(output_msg, "running", -1); break;
    case PROCESS_STATE_STOPPING: msgpack_pack_string(output_msg, "stopping", -1); break;
    case PROCESS_STATE_EXITED: msgpack_pack_string(output_msg, "exited", -1); break;
    case PROCESS_STATE_BACKOFF: msgpack_pack_string(output_msg, "backoff", -1); break;
    case PROCESS_STATE_NEW: msgpack_pack_string(output_msg, "new", -1); break;
    default: msgpack_pack_string(output_msg, "unknown", -1); break;
  }

  if (process->state == PROCESS_STATE_EXITED
      || process->state == PROCESS_STATE_BACKOFF) {
    msgpack_pack_string(output_msg, "code", -1);
    msgpack_pack_nil(output_msg);
  } else if (process->exit_signal == 0) {
    msgpack_pack_string(output_msg, "code", -1);
    msgpack_pack_int(output_msg, process->exit_status);
  } else {
    msgpack_pack_string(output_msg, "signal", -1);

    /* lol. */
    switch (process->exit_signal) {
      case SIGHUP: msgpack_pack_string(output_msg, "HUP", 3); break;
      case SIGINT: msgpack_pack_string(output_msg, "INT", 3); break;
      case SIGQUIT: msgpack_pack_string(output_msg, "QUIT", 4); break;
      case SIGILL: msgpack_pack_string(output_msg, "ILL", 3); break;
      case SIGTRAP: msgpack_pack_string(output_msg, "TRAP", 4); break;
      case SIGABRT: msgpack_pack_string(output_msg, "ABRT", 4); break;
      case SIGBUS: msgpack_pack_string(output_msg, "BUS", 3); break;
      case SIGFPE: msgpack_pack_string(output_msg, "FPE", 3); break;
      case SIGKILL: msgpack_pack_string(output_msg, "KILL", 4); break;
      case SIGUSR1: msgpack_pack_string(output_msg, "USR1", 4); break;
      case SIGSEGV: msgpack_pack_string(output_msg, "SEGV", 4); break;
      case SIGUSR2: msgpack_pack_string(output_msg, "USR2", 4); break;
      case SIGPIPE: msgpack_pack_string(output_msg, "PIPE", 4); break;
      case SIGALRM: msgpack_pack_string(output_msg, "ALRM", 4); break;
      case SIGTERM: msgpack_pack_string(output_msg, "TERM", 4); break;
      case SIGSTKFLT: msgpack_pack_string(output_msg, "STKFLT", 6); break;
      case SIGCHLD: msgpack_pack_string(output_msg, "CHLD", 4); break;
      case SIGCONT: msgpack_pack_string(output_msg, "CONT", 4); break;
      case SIGSTOP: msgpack_pack_string(output_msg, "STOP", 4); break;
      case SIGTSTP: msgpack_pack_string(output_msg, "TSTP", 4); break;
      case SIGTTIN: msgpack_pack_string(output_msg, "TTIN", 4); break;
      case SIGTTOU: msgpack_pack_string(output_msg, "TTOU", 4); break;
      case SIGURG: msgpack_pack_string(output_msg, "URG", 3); break;
      case SIGXCPU: msgpack_pack_string(output_msg, "XCPU", 4); break;
      case SIGXFSZ: msgpack_pack_string(output_msg, "XFSZ", 4); break;
      case SIGVTALRM: msgpack_pack_string(output_msg, "VTALRM", 5); break;
      case SIGPROF: msgpack_pack_string(output_msg, "PROF", 4); break;
      case SIGWINCH: msgpack_pack_string(output_msg, "WINCH", 5); break;
      case SIGPOLL: msgpack_pack_string(output_msg, "POLL", 4); break;
      case SIGPWR: msgpack_pack_string(output_msg, "PWR", 3); break;
      case SIGSYS: msgpack_pack_string(output_msg, "SYS", 3); break;
      default: msgpack_pack_string(output_msg, "unknown", -1); break;
    } /* switch process->exit_signal */
  } /* if process was killed by a signal */

  zmq_msg_init_data(&event, buffer->data, buffer->size, free_msgpack_buffer, buffer); 
  zmq_send(pn->eventsocket, &event, 0);
  zmq_msg_close(&event);

  msgpack_packer_free(output_msg);
} /* publish_output */
示例#13
0
void rpc_handle(rpc_io *rpcio, zmq_msg_t *request) {
  /* Parse the msgpack */
  zmq_msg_t response;
  int rc;
  msgpack_unpacked request_msg;
  msgpack_unpacked_init(&request_msg);
  rc = msgpack_unpack_next(&request_msg, zmq_msg_data(request),
                           zmq_msg_size(request), NULL);
  insist_return(rc, (void)(0), "Failed to unpack message '%.*s'",
                zmq_msg_size(request), zmq_msg_data(request));

  msgpack_object request_obj = request_msg.data;
  printf("Object: ");
  msgpack_object_print(stdout, request_obj);  /*=> ["Hello", "MessagePack"] */
  printf("\n");

  /* Find the method name */
  char *method = NULL;
  size_t method_len = -1;
  rc = obj_get(&request_obj, "request", MSGPACK_OBJECT_RAW, &method, &method_len);
  msgpack_sbuffer *buffer = msgpack_sbuffer_new();
  msgpack_packer *response_msg = msgpack_packer_new(buffer, msgpack_sbuffer_write);

  printf("Method: %.*s\n", method_len, method);

  if (rc != 0) {
    fprintf(stderr, "Message had no 'request' field. Ignoring: ");
    msgpack_object_print(stderr, request_obj);
    msgpack_pack_map(response_msg, 2);
    msgpack_pack_string(response_msg, "error", -1);
    msgpack_pack_string(response_msg, "Message had no 'request' field", -1);
    msgpack_pack_string(response_msg, "request", -1);
    msgpack_pack_object(response_msg, request_obj);
  } else {
    /* Found request */
    printf("The method is: '%.*s'\n", (int)method_len, method);

    //msgpack_pack_map(response_msg, 2);
    //msgpack_pack_string(response_msg, "results", 7);

    void *clock = zmq_stopwatch_start();
    /* TODO(sissel): Use gperf here or allow methods to register themselves */
    if (!strncmp("dance", method, method_len)) {
      api_request_dance(rpcio, &request_obj, response_msg);
    } else if (!strncmp("restart", method, method_len)) {
      api_request_restart(rpcio, &request_obj, response_msg);
    } else if (!strncmp("status", method, method_len)) {
      api_request_status(rpcio, &request_obj, response_msg);
    } else if (!strncmp("create", method, method_len)) {
      api_request_create(rpcio, &request_obj, response_msg);
    } else {
      fprintf(stderr, "Invalid request '%.*s' (unknown method): ", method_len, method);
      msgpack_object_print(stderr, request_obj);
      msgpack_pack_map(response_msg, 2);
      msgpack_pack_string(response_msg, "error", -1);
      msgpack_pack_string(response_msg, "No such method requested", -1);
      msgpack_pack_string(response_msg, "request", -1);
      msgpack_pack_object(response_msg, request_obj);
    }
    double duration = zmq_stopwatch_stop(clock) / 1000000.;

    printf("method '%.*s' took %lf seconds\n", (int)method_len, method);

    //msgpack_pack_string(response_msg, "stats", 5);
    //msgpack_pack_map(response_msg, 1),
    //msgpack_pack_string(response_msg, "duration", 8);
    //msgpack_pack_double(response_msg, duration);
  }

  zmq_msg_init_data(&response, buffer->data, buffer->size, free_msgpack_buffer, buffer); 
  zmq_send(rpcio->socket, &response, 0);
  zmq_msg_close(&response);

  //msgpack_sbuffer_free(buffer);
  msgpack_packer_free(response_msg);
  msgpack_unpacked_destroy(&request_msg);
} /* rpc_handle */
示例#14
0
void rpc_service_handle(rpc_service_t *service, zmq_msg_t *request) {
  /* Parse the msgpack */
  zmq_msg_t response;
  int rc;
  msgpack_unpacked request_msg;
  msgpack_unpacked_init(&request_msg);
  rc = msgpack_unpack_next(&request_msg, zmq_msg_data(request),
                           zmq_msg_size(request), NULL);
  insist_return(rc, (void)(0), "Failed to unpack message '%.*s'",
                (int)zmq_msg_size(request), (char *)zmq_msg_data(request));

  msgpack_object request_obj = request_msg.data;

  /* Find the method name */
  char *method = NULL;
  size_t method_len = -1;
  rc = obj_get(&request_obj, "method", MSGPACK_OBJECT_RAW, &method, &method_len);

  msgpack_sbuffer *response_buffer = msgpack_sbuffer_new();
  msgpack_sbuffer *result_buffer = msgpack_sbuffer_new();
  msgpack_sbuffer *error_buffer = msgpack_sbuffer_new();

  msgpack_packer *response_msg = msgpack_packer_new(response_buffer, msgpack_sbuffer_write);
  msgpack_packer *result = msgpack_packer_new(result_buffer, msgpack_sbuffer_write);
  msgpack_packer *error = msgpack_packer_new(error_buffer, msgpack_sbuffer_write);

  //printf("Method: %.*s\n", method_len, method);

  void *clock = zmq_stopwatch_start();
  double duration;

  if (rc != 0) { /* method not found */
    msgpack_pack_nil(result); /* result is nil on error */
    msgpack_pack_map(error, 2);
    msgpack_pack_string(error, "error", -1);
    msgpack_pack_string(error, "Message had no 'method' field", -1);
    msgpack_pack_string(error, "request", -1);
    msgpack_pack_object(error, request_obj);
  } else { /* valid method, keep going */
    //printf("The method is: '%.*s'\n", (int)method_len, method);
    rpc_name name;
    name.name = method;
    name.len = method_len;

    rpc_method *rpcmethod = g_tree_lookup(service->methods, &name);

    /* if we found a valid rpc method and the args check passed ... */
    if (rpcmethod != NULL) {
      /* the callback is responsible for filling in the 'result' and 'error' 
       * objects. */
      rpcmethod->callback(NULL, &request_obj, result, error, rpcmethod->data);
    } else {
      msgpack_pack_nil(result); /* result is nil on error */

      /* TODO(sissel): allow methods to register themselves */
      //fprintf(stderr, "Invalid request '%.*s' (unknown method): ",
              //method_len, method);
      //msgpack_object_print(stderr, request_obj);
      //fprintf(stderr, "\n");

      msgpack_pack_map(error, 2);
      msgpack_pack_string(error, "error", -1);
      msgpack_pack_string(error, "No such method requested", -1);
      msgpack_pack_string(error, "request", -1);
      msgpack_pack_object(error, request_obj);
    }
  } /* valid/invalid method handling */

  duration = zmq_stopwatch_stop(clock) / 1000000.;
  //printf("method '%.*s' took %lf seconds\n", (int)method_len, method);

  msgpack_unpacked result_unpacked;
  msgpack_unpacked error_unpacked;
  msgpack_unpacked response_unpacked;
  msgpack_unpacked_init(&result_unpacked);
  msgpack_unpacked_init(&error_unpacked);
  msgpack_unpacked_init(&response_unpacked);

  /* TODO(sissel): If this unpack test fails, we should return an error to the calling
   * client indicating that some internal error has occurred */
  //fprintf(stderr, "Result payload: '%.*s'\n", result_buffer->size,
  //result_buffer->data);
  rc = msgpack_unpack_next(&result_unpacked, result_buffer->data,
                           result_buffer->size, NULL);
  insist(rc == true, "msgpack_unpack_next failed on 'result' buffer"
         " of request '%.*s'", (int)method_len, method);
  rc = msgpack_unpack_next(&error_unpacked, error_buffer->data,
                           error_buffer->size, NULL);
  insist(rc == true, "msgpack_unpack_next failed on 'error' buffer"
         " of request '%.*s'", (int)method_len, method);

  msgpack_pack_map(response_msg, 3); /* result, error, duration */
  msgpack_pack_string(response_msg, "result", 6);
  msgpack_pack_object(response_msg, result_unpacked.data);
  msgpack_pack_string(response_msg, "error", 5);
  msgpack_pack_object(response_msg, error_unpacked.data);
  msgpack_pack_string(response_msg, "duration", 8);
  msgpack_pack_double(response_msg, duration);

  rc = msgpack_unpack_next(&response_unpacked, response_buffer->data,
                           response_buffer->size, NULL);
  insist(rc == true, "msgpack_unpack_next failed on full response buffer"
         " of request '%.*s'", (int)method_len, method);

  //printf("request: ");
  //msgpack_object_print(stdout, request_obj);
  //printf("\n");
  //printf("response: ");
  //msgpack_object_print(stdout, response_unpacked.data);
  //printf("\n");

  zmq_msg_init_data(&response, response_buffer->data, response_buffer->size,
                    free_msgpack_buffer, response_buffer);
  zmq_send(service->socket, &response, 0);
  zmq_msg_close(&response);

  msgpack_packer_free(error);
  msgpack_packer_free(result);
  msgpack_sbuffer_free(error_buffer);
  msgpack_sbuffer_free(result_buffer);
  msgpack_packer_free(response_msg);
  msgpack_unpacked_destroy(&request_msg);
} /* rpc_service_handle */