Revision 98b047dd

View differences:

include/cloud_helper.h
68 68
                   uint8_t *header_ptr, int header_size, int free_header);
69 69

  
70 70
/**
71
 * @brief Get the value for key or return default value
72
 * This function send a request to the cloud for the value associated to the
73
 * specified key. Use the wait4cloud to listen for the answer and
74
 * revc_from_cloud to read the response.
75
 *
76
 * If the specified key isn't present on the cloud, return the default value
77
 * @param[in] context The contex representing the desired cloud_helper
78
 *                    instance.
79
 * @param[in] key Key to retrieve.
80
 * @param[in] header_ptr A pointer to the header which will be added to the
81
 *                       retrieved data. May be NULL
82
 * @param[in] header_size The length of the header.
83
 * @param[in] free_header A positive value result in buffer_ptr being freed
84
 *                        on request completion
85
 * @param[in] defval_ptr A pointer to the default value to use if key is missing
86
 * @param[in] defval_size The length of the default value
87
 * @param[in] free_defvar A positive value result in defval_ptr being freed on
88
                          request comletion
89
 * @return 0 if the request was successfully sent, 1 Otherwise
90
 */
91
int get_from_cloud_default(struct cloud_helper_context *context, const char *key,
92
                           uint8_t *header_ptr, int header_size, int free_header,
93
                           uint8_t *defval_ptr, int defval_size, int free_defval);
94

  
95
/**
71 96
 * @brief Returns the timestamp associated to the last GET operation.
72 97
 * Returns the timestamp associated to the last GET operation or NULL.
73 98
 * @param[in] context The contex representing the desired cloud_helper
src/CloudSupport/cloud_helper.c
126 126
                                     header_size, free_header);
127 127
}
128 128

  
129
int get_from_cloud_default(struct cloud_helper_context *context, const char *key,
130
                           uint8_t *header_ptr, int header_size, int free_header,
131
                           uint8_t *defval_ptr, int defval_size, int free_defval)
132
{
133
  return context->ch->get_from_cloud_default(context->ch_context, key, header_ptr,
134
                                             header_size, free_header, defval_ptr,
135
                                             defval_size, free_defval);
136
}
137

  
129 138
int put_on_cloud(struct cloud_helper_context *context, const char *key,
130 139
                 uint8_t *buffer_ptr, int buffer_size, int free_buffer)
131 140
{
src/CloudSupport/cloud_helper_delegate.c
18 18
  int (*get_from_cloud)(void *context, const char *key, uint8_t *header_ptr,
19 19
                        int header_size, int free_header);
20 20

  
21
  int (*get_from_cloud_default)(void *context, const char *key,
22
                                uint8_t *header_ptr, int header_size, int free_header,
23
                                uint8_t *defval_ptr, int defval_size, int free_defval);
24

  
21 25
  int (*put_on_cloud)(void *context, const char *key, uint8_t *buffer_ptr,
22 26
                      int buffer_size, int free_buffer);
23 27

  
......
81 85
}
82 86

  
83 87
static int
88
delegate_cloud_get_from_cloud_default(struct cloud_helper_impl_context *context,
89
                                      const char *key, uint8_t *header_ptr,
90
                                      int header_size, int free_header,
91
                                      uint8_t *defval_ptr, int defval_size,
92
                                      int free_defval)
93
{
94
  return context->delegate->get_from_cloud_default(context->delegate_context,
95
                                                   key, header_ptr, header_size,
96
                                                   free_header, defval_ptr,
97
                                                   defval_size, free_defval);
98
}
99

  
100
static int
84 101
delegate_cloud_put_on_cloud(struct cloud_helper_impl_context *context,
85 102
                            const char *key, uint8_t *buffer_ptr,
86 103
                            int buffer_size, int free_buffer)
......
124 141
struct cloud_helper_iface delegate = {
125 142
  .cloud_helper_init = delegate_cloud_init,
126 143
  .get_from_cloud = delegate_cloud_get_from_cloud,
144
  .get_from_cloud_default = delegate_cloud_get_from_cloud_default,
127 145
  .put_on_cloud = delegate_cloud_put_on_cloud,
128 146
  .get_cloud_node = delegate_cloud_get_cloud_node,
129 147
  .timestamp_cloud = delegate_timestamp_cloud,
src/CloudSupport/cloud_helper_iface.h
14 14
                        const char *key, uint8_t *header_ptr, int header_size,
15 15
                        int free_header);
16 16

  
17
  int (*get_from_cloud_default)(struct cloud_helper_impl_context *context, const char *key,
18
                                uint8_t *header_ptr, int header_size, int free_header,
19
                                uint8_t *defval_ptr, int defval_size, int free_defval);
20

  
17 21
  int (*put_on_cloud)(struct cloud_helper_impl_context *context,
18 22
                      const char *key, uint8_t *buffer_ptr, int buffer_size,
19 23
                      int free_buffer);
src/CloudSupport/libs3_delegate_helper.c
36 36
  void* (*cloud_helper_init)(struct nodeID *local, const char *config);
37 37
  int (*get_from_cloud)(void *context, const char *key, uint8_t *header_ptr,
38 38
                        int header_size, int free_header);
39
  int (*get_from_cloud_default)(void *context, const char *key,
40
                                uint8_t *header_ptr, int header_size, int free_header,
41
                                uint8_t *defval_ptr, int defval_size, int free_defval);
39 42
  int (*put_on_cloud)(void *context, const char *key, uint8_t *buffer_ptr,
40 43
                      int buffer_size, int free_buffer);
41 44
  struct nodeID* (*get_cloud_node)(void *context, uint8_t variant);
......
121 124
  int data_length;
122 125
  int free_data;
123 126

  
127
  uint8_t *default_value;
128
  int default_value_length;
129
  int free_default_value;
130

  
124 131
  struct libs3_cloud_context *ctx;
125 132
};
126 133
typedef struct libs3_request libs3_request_t;
......
163 170

  
164 171
  free(req->key);
165 172
  if (req->free_data > 0) free(req->data);
173
  if (req->free_default_value > 0)
174
    free(req->default_value);
166 175

  
167 176
  free(req);
168 177
}
......
432 441
    rsp->data_length = cbk_ctx->bytes + req->data_length;
433 442
    rsp->read_bytes = 0;
434 443
    rsp->last_timestamp = cbk_ctx->last_timestamp;
444
  } else {
445
    /* Since there was no value for the specified key. If the caller specified a
446
       default value, use that */
447
    if (req->default_value) {
448
      rsp->data = malloc(req->data_length + req->default_value_length);
449
      if (!rsp->data) return 1;
450
      rsp->current_byte = rsp->data;
451
      if (req->data_length > 0)
452
        memcpy(rsp->data, req->data, req->data_length);
453

  
454
      memcpy(rsp->data, req->default_value, req->default_value_length);
455

  
456
      rsp->status = S3StatusOK;
457
    }
435 458
  }
436 459

  
437
  status = (cbk_ctx->status == S3StatusOK) ? 0 : -1;
438 460
  free(cbk_ctx);
461
  status = (rsp->status == S3StatusOK) ? 0 : -1;
462

  
439 463

  
440 464
  return status;
441 465
}
......
536 560
  return ctx;
537 561
}
538 562

  
539
int get_from_cloud(void *context, const char *key, uint8_t *header_ptr,
540
                   int header_size, int free_header)
563
int get_from_cloud_default(void *context, const char *key, uint8_t *header_ptr,
564
                           int header_size, int free_header, uint8_t *defval_ptr,
565
                           int defval_size, int free_defval)
541 566
{
542 567
  struct libs3_cloud_context *ctx;
543 568
  libs3_request_t *request;
......
552 577
  request->data = header_ptr;
553 578
  request->data_length = header_size;
554 579
  request->free_data = free_header;
580
  request->default_value = defval_ptr;
581
  request->default_value_length = defval_size;
582
  request->free_default_value = free_defval;
555 583
  request->ctx = ctx;
556 584

  
557 585
  req_handler_add_request(ctx->req_handler,
......
562 590
  return 0;
563 591
}
564 592

  
593
int get_from_cloud(void *context, const char *key, uint8_t *header_ptr,
594
                   int header_size, int free_header)
595
{
596
  return get_from_cloud_default(context, key, header_ptr, header_size,
597
                                free_header, NULL, 0, 0);
598
}
599

  
565 600
int put_on_cloud(void *context, const char *key, uint8_t *buffer_ptr,
566 601
                 int buffer_size, int free_buffer)
567 602
{
......
578 613
  request->data = buffer_ptr;
579 614
  request->data_length = buffer_size;
580 615
  request->free_data = free_buffer;
616
  request->default_value = NULL;
617
  request->default_value_length = 0;
618
  request->free_default_value = 0;
581 619
  request->ctx = ctx;
582 620

  
583 621
  if (ctx->blocking_put_request) {
......
676 714
struct delegate_iface delegate_impl = {
677 715
  .cloud_helper_init = &cloud_helper_init,
678 716
  .get_from_cloud = &get_from_cloud,
717
  .get_from_cloud_default = &get_from_cloud_default,
679 718
  .put_on_cloud = &put_on_cloud,
680 719
  .get_cloud_node = &get_cloud_node,
681 720
  .timestamp_cloud = &timestamp_cloud,
src/CloudSupport/mysql_delegate_helper.c
37 37
  void* (*cloud_helper_init)(struct nodeID *local, const char *config);
38 38
  int (*get_from_cloud)(void *context, const char *key, uint8_t *header_ptr,
39 39
                        int header_size, int free_header);
40
  int (*get_from_cloud_default)(void *context, const char *key,
41
                                uint8_t *header_ptr, int header_size, int free_header,
42
                                uint8_t *defval_ptr, int defval_size, int free_defval);
40 43
  int (*put_on_cloud)(void *context, const char *key, uint8_t *buffer_ptr,
41 44
                      int buffer_size, int free_buffer);
42 45
  struct nodeID* (*get_cloud_node)(void *context, uint8_t variant);
......
66 69
  int data_length;
67 70
  int free_data;
68 71

  
72
  uint8_t *default_value;
73
  int default_value_length;
74
  int free_default_value;
69 75
  struct mysql_cloud_context *helper_ctx;
70 76
};
71 77
typedef struct mysql_request mysql_request_t;
......
148 154
  req = (mysql_request_t *) req_ptr;
149 155
  if (req->free_data) free(req->data);
150 156

  
157
  if (req->free_default_value > 0)
158
    free(req->default_value);
159

  
151 160
  free(req);
152 161
  return;
153 162
}
......
220 229
      ts_str[field_len[1]] = '\0';
221 230
      rsp->last_timestamp = strtol(ts_str, NULL, 10);
222 231
      rsp->status = SUCCESS;
232
    } else {
233
      /* Since there was no value for the specified key. If the caller specified a
234
         default value, use that */
235
      if (req->default_value) {
236
        /* reserve space for value and header */
237
        rsp->data_length = req->default_value_length + req->data_length;
238
        rsp->data = calloc(rsp->data_length, sizeof(char));
239
        rsp->current_byte = rsp->data;
240

  
241
        if (req->data_length > 0)
242
          memcpy(rsp->data, req->data, req->data_length);
243

  
244
        memcpy(rsp->data + req->data_length,
245
               req->default_value, req->default_value_length);
246

  
247
        rsp->last_timestamp = 0;
248
        rsp->status = SUCCESS;
249
      }
223 250
    }
224 251
    mysql_free_result(result);
225 252
  }
......
339 366
  return ctx;
340 367
}
341 368

  
342
int get_from_cloud(void *context, const char *key, uint8_t *header_ptr,
343
                   int header_size, int free_header)
369
int get_from_cloud_default(void *context, const char *key,
370
                           uint8_t *header_ptr, int header_size, int free_header,
371
                           uint8_t *defval_ptr, int defval_size, int free_defval)
344 372
{
345 373
  struct mysql_cloud_context *ctx;
346 374
  mysql_request_t *request;
......
356 384
  request->data = header_ptr;
357 385
  request->data_length = header_size;
358 386
  request->free_data = free_header;
387
  request->default_value = defval_ptr;
388
  request->default_value_length = defval_size;
389
  request->free_default_value = free_defval;
359 390
  request->helper_ctx = ctx;
360 391

  
361 392
  err = req_handler_add_request(ctx->req_handler, &process_get_operation,
......
365 396
  return err;
366 397
}
367 398

  
399
int get_from_cloud(void *context, const char *key, uint8_t *header_ptr,
400
                   int header_size, int free_header)
401
{
402
  return get_from_cloud_default(context, key, header_ptr, header_size,
403
                                free_header, NULL, 0, 0);
404
}
405

  
368 406

  
369 407
int put_on_cloud(void *context, const char *key, uint8_t *buffer_ptr,
370 408
                 int buffer_size, int free_buffer)
......
383 421
  request->data = buffer_ptr;
384 422
  request->data_length = buffer_size;
385 423
  request->free_data = free_buffer;
386

  
424
  request->default_value = NULL;
425
  request->default_value_length = 0;
426
  request->free_default_value = 0;
387 427
  res = process_put_operation(ctx, request);
388 428
  free_request(request);
389 429
  return res;
......
472 512
struct delegate_iface delegate_impl = {
473 513
  .cloud_helper_init = &cloud_helper_init,
474 514
  .get_from_cloud = &get_from_cloud,
515
  .get_from_cloud_default = &get_from_cloud_default,
475 516
  .put_on_cloud = &put_on_cloud,
476 517
  .get_cloud_node = &get_cloud_node,
477 518
  .timestamp_cloud = &timestamp_cloud,
src/Tests/cloud_test.c
5 5
 *
6 6
 *  This is a small test program for the cloud interface
7 7
 *  To try the simple test: run it with
8
 *    ./cloud_test -c "provider=<cloud_provider>,<provider_opts>" [-g key | -p key=value | -n variant | -e ip:port]
8
 *    ./cloud_test -c "provider=<cloud_provider>,<provider_opts>" [-g key | -d key=value | -p key=value | -n variant | -e ip:port]
9 9
 *
10 10
 *    -g  GET key from cloud
11
 *    -d  GET key from cloud with default
11 12
 *    -p  PUT key=value on cloud
12 13
 *    -n  print the cloud node for the specified variant
13 14
 *    -e  check if ip:port references the cloud
......
33 34
#define PUT 1
34 35
#define GET_CLOUD_NODE 2
35 36
#define EQ_CLOUD_NODE 3
37
#define GETDEF 4
36 38

  
37 39
static const char *config;
38 40
static int operation;
......
47 49
  int o;
48 50
  char *temp;
49 51

  
50
  while ((o = getopt(argc, argv, "c:g:p:n:e:")) != -1) {
52
  while ((o = getopt(argc, argv, "c:g:d:p:n:e:")) != -1) {
51 53
    switch(o) {
52 54
    case 'c':
53 55
      config = strdup(optarg);
......
65 67
        exit(-1);
66 68
      }
67 69
      break;
68
      case 'g':
70
    case 'g':
69 71
        key =  strdup(optarg);
70 72
        break;
73
    case 'd':
74
      temp = strdup(optarg);
75
      operation = GETDEF;
76

  
77
      key = strsep(&optarg, "=");
78
      value = optarg;
79

  
80
      if (!value || !key){
81
        printf("Expected key=value for option -d");
82
        free(temp);
83
        exit(-1);
84
      }
85
      break;
71 86
    case 'n':
72 87
      operation = GET_CLOUD_NODE;
73 88
      variant = atoi(optarg);
......
140 155
      return 1;
141 156
    }
142 157
    break;
158
  case GETDEF:
143 159
  case GET:
144 160
    printf("Getting from cloud value for key \"%s\": ", key);
145 161
    memcpy(buffer, HEADER, strlen(HEADER));
146
    err = get_from_cloud(cloud, key, buffer, strlen(HEADER), 0);
162

  
163
    if (operation == GETDEF) {
164
      printf("(Using default value: \"%s\")", value);
165
      err = get_from_cloud_default(cloud, key, buffer, strlen(HEADER), 0,
166
                                   value, strlen(value), 0);
167
    } else {
168
      err = get_from_cloud(cloud, key, buffer, strlen(HEADER), 0);
169
    }
170

  
147 171
    if (err) {
148 172
      printf("Error performing the operation");
149 173
      return 1;
......
170 194
      printf("No response from cloud\n");
171 195
      return 1;
172 196
    } else {
197
      memset(buffer, 0, sizeof(buffer));
173 198
      err = recv_from_cloud(cloud, buffer, sizeof(buffer)-1);
174 199
      buffer[sizeof(buffer) - 1] = '\0';
175 200
      printf("No value for the specified key. Received: %s\n", buffer);

Also available in: Unified diff