kinetic-c  v0.12.0
Seagate Kinetic Protocol Client Library for C
kinetic_callbacks.c
Go to the documentation of this file.
1 /*
2 * kinetic-c
3 * Copyright (C) 2015 Seagate Technology.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 *
19 */
20 #include "kinetic_operation.h"
21 #include "kinetic_controller.h"
22 #include "kinetic_session.h"
23 #include "kinetic_message.h"
24 #include "kinetic_bus.h"
25 #include "kinetic_response.h"
26 #include "kinetic_device_info.h"
27 #include "kinetic_allocator.h"
28 #include "kinetic_logger.h"
29 #include "kinetic_request.h"
30 #include "kinetic_acl.h"
31 
32 #include <stdlib.h>
33 #include <errno.h>
34 #include <sys/time.h>
35 #include <stdio.h>
36 
37 #include "kinetic_acl.h"
38 
39 /*******************************************************************************
40  * Standard Client Operations
41 *******************************************************************************/
42 
43 KineticStatus KineticCallbacks_Basic(KineticOperation* const operation, KineticStatus const status)
44 {
45  KINETIC_ASSERT(operation != NULL);
46  KINETIC_ASSERT(operation->session != NULL);
47  return status;
48 }
49 
50 KineticStatus KineticCallbacks_Put(KineticOperation* const operation, KineticStatus const status)
51 {
52  KINETIC_ASSERT(operation != NULL);
53  KINETIC_ASSERT(operation->session != NULL);
54  KINETIC_ASSERT(operation->entry != NULL);
55 
56  if (status == KINETIC_STATUS_SUCCESS)
57  {
58  KINETIC_ASSERT(operation->response != NULL);
59  // Propagate newVersion to dbVersion in metadata, if newVersion specified
60  KineticEntry* entry = operation->entry;
61  if (entry->newVersion.array.data != NULL && entry->newVersion.array.len > 0) {
62  // If both buffers supplied, copy newVersion into dbVersion, and clear newVersion
63  if (entry->dbVersion.array.data != NULL && entry->dbVersion.array.len > 0) {
64  ByteBuffer_Reset(&entry->dbVersion);
67  }
68 
69  // If only newVersion buffer supplied, move newVersion buffer into dbVersion,
70  // and set newVersion to NULL buffer
71  else {
72  entry->dbVersion = entry->newVersion;
74  }
75  }
76  }
77  return status;
78 }
79 
80 KineticStatus KineticCallbacks_Get(KineticOperation* const operation, KineticStatus const status)
81 {
82  KINETIC_ASSERT(operation != NULL);
83  KINETIC_ASSERT(operation->session != NULL);
84  KINETIC_ASSERT(operation->entry != NULL);
85 
86  if (status == KINETIC_STATUS_SUCCESS)
87  {
88  KINETIC_ASSERT(operation->response != NULL);
89  // Update the entry upon success
90  Com__Seagate__Kinetic__Proto__Command__KeyValue* keyValue = KineticResponse_GetKeyValue(operation->response);
91  if (keyValue != NULL) {
94  }
95  }
96 
97  if (!operation->entry->metadataOnly &&
98  !ByteBuffer_IsNull(operation->entry->value))
99  {
100  ByteBuffer_AppendArray(&operation->entry->value, (ByteArray){
101  .data = operation->response->value,
102  .len = operation->response->header.valueLength,
103  });
104  }
105  }
106 
107  return status;
108 }
109 
110 KineticStatus KineticCallbacks_Delete(KineticOperation* const operation, KineticStatus const status)
111 {
112  KINETIC_ASSERT(operation != NULL);
113  KINETIC_ASSERT(operation->session != NULL);
114  KINETIC_ASSERT(operation->entry != NULL);
115  return status;
116 }
117 
118 KineticStatus KineticCallbacks_GetKeyRange(KineticOperation* const operation, KineticStatus const status)
119 {
120  KINETIC_ASSERT(operation != NULL);
121  KINETIC_ASSERT(operation->session != NULL);
122  KINETIC_ASSERT(operation->buffers != NULL);
123  KINETIC_ASSERT(operation->buffers->count > 0);
124 
125  if (status == KINETIC_STATUS_SUCCESS)
126  {
127  KINETIC_ASSERT(operation->response != NULL);
128  // Report the key list upon success
129  Com__Seagate__Kinetic__Proto__Command__Range* keyRange = KineticResponse_GetKeyRange(operation->response);
130  if (keyRange != NULL) {
133  }
134  }
135  }
136  return status;
137 }
138 
139 static void populateP2PStatusCodes(KineticP2P_Operation* const p2pOp, Com__Seagate__Kinetic__Proto__Command__P2POperation const * const p2pOperation)
140 {
141  if (p2pOperation == NULL) { return; }
142  for(size_t i = 0; i < p2pOp->numOperations; i++)
143  {
144  if (i < p2pOperation->n_operation)
145  {
146  if ((p2pOperation->operation[i]->status != NULL) &&
147  (p2pOperation->operation[i]->status->has_code))
148  {
149  p2pOp->operations[i].resultStatus = KineticProtoStatusCode_to_KineticStatus(
150  p2pOperation->operation[i]->status->code);
151  }
152  else
153  {
154  p2pOp->operations[i].resultStatus = KINETIC_STATUS_INVALID;
155  }
156  if ((p2pOp->operations[i].chainedOperation != NULL) &&
157  (p2pOperation->operation[i]->p2pop != NULL)) {
158  populateP2PStatusCodes(p2pOp->operations[i].chainedOperation, p2pOperation->operation[i]->p2pop);
159  }
160  }
161  else
162  {
163  p2pOp->operations[i].resultStatus = KINETIC_STATUS_INVALID;
164  }
165  }
166 }
167 
168 KineticStatus KineticCallbacks_P2POperation(KineticOperation* const operation, KineticStatus const status)
169 {
170  KINETIC_ASSERT(operation != NULL);
171  KINETIC_ASSERT(operation->session != NULL);
172  KineticP2P_Operation* const p2pOp = operation->p2pOp;
173 
174  if (status == KINETIC_STATUS_SUCCESS)
175  {
176  if ((operation->response != NULL) &&
177  (operation->response->command != NULL) &&
178  (operation->response->command->body != NULL) &&
179  (operation->response->command->body->p2poperation != NULL)) {
180  populateP2PStatusCodes(p2pOp, operation->response->command->body->p2poperation);
181  }
182  }
183 
184  KineticAllocator_FreeP2PProtobuf(operation->request->command->body->p2poperation);
185 
186  return status;
187 }
188 
189 
190 /*******************************************************************************
191  * Admin Client Operations
192 *******************************************************************************/
193 
194 KineticStatus KineticCallbacks_GetLog(KineticOperation* const operation, KineticStatus const status)
195 {
196  KINETIC_ASSERT(operation != NULL);
197  KINETIC_ASSERT(operation->session != NULL);
198  KINETIC_ASSERT(operation->deviceInfo != NULL);
199 
200  if (status == KINETIC_STATUS_SUCCESS)
201  {
202  KINETIC_ASSERT(operation->response != NULL);
203  // Copy the data from the response protobuf into a new info struct
204  if (operation->response->command->body->getlog == NULL) {
206  }
207  else {
208  *operation->deviceInfo = KineticLogInfo_Create(operation->response->command->body->getlog);
209  return KINETIC_STATUS_SUCCESS;
210  }
211  }
212  return status;
213 }
214 
215 KineticStatus KineticCallbacks_SetClusterVersion(KineticOperation* const operation, KineticStatus const status)
216 {
217  KINETIC_ASSERT(operation != NULL);
218  KINETIC_ASSERT(operation->session != NULL);
219  if (status == KINETIC_STATUS_SUCCESS) {
220  KineticSession_SetClusterVersion(operation->session, operation->pendingClusterVersion);
221  operation->pendingClusterVersion = -1; // Invalidate
222  }
223  return status;
224 }
225 
226 KineticStatus KineticCallbacks_SetACL(KineticOperation* const operation, KineticStatus const status)
227 {
228  KINETIC_ASSERT(operation != NULL);
229  KINETIC_ASSERT(operation->session != NULL);
230  if (operation->request != NULL &&
231  operation->request->command != NULL &&
232  operation->request->command->body != NULL &&
233  operation->request->command->body->security != NULL &&
234  operation->request->command->body->security->acl != NULL)
235  {
236  struct ACL* acls = calloc(1, sizeof(struct ACL));
237  acls->ACL_count = operation->request->command->body->security->n_acl,
238  acls->ACLs = operation->request->command->body->security->acl,
239  KineticACL_Free(acls);
240  }
241  return status;
242 }
243 
244 KineticStatus KineticCallbacks_UpdateFirmware(KineticOperation* const operation, KineticStatus const status)
245 {
246  KINETIC_ASSERT(operation != NULL);
247  KINETIC_ASSERT(operation->session != NULL);
248 
249  if (operation->value.data != NULL) {
250  free(operation->value.data);
251  memset(&operation->value, 0, sizeof(ByteArray));
252  }
253 
254  return status;
255 }
Structure for handling generic arrays of bytes.
Definition: byte_array.h:34
void ByteBuffer_Reset(ByteBuffer *buffer)
Definition: byte_array.c:62
KineticStatus KineticProtoStatusCode_to_KineticStatus(Com__Seagate__Kinetic__Proto__Command__Status__StatusCode protoStatus)
ByteBuffer * ByteBuffer_Append(ByteBuffer *buffer, const void *data, size_t len)
Definition: byte_array.c:135
One or more of byte buffers did not fit all data.
Operation successful.
KineticStatus KineticCallbacks_Get(KineticOperation *const operation, KineticStatus const status)
KineticStatus KineticCallbacks_Delete(KineticOperation *const operation, KineticStatus const status)
void KineticACL_Free(struct ACL *ACLs)
Definition: kinetic_acl.c:436
void KineticSession_SetClusterVersion(KineticSession *const session, int64_t cluster_version)
ByteBuffer * ByteBuffer_AppendArray(ByteBuffer *buffer, const ByteArray array)
Definition: byte_array.c:149
bool Copy_Com__Seagate__Kinetic__Proto__Command__Range_to_ByteBufferArray(Com__Seagate__Kinetic__Proto__Command__Range *keyRange, ByteBufferArray *keys)
Com__Seagate__Kinetic__Proto__Command__KeyValue * KineticResponse_GetKeyValue(KineticResponse *response)
ByteArray array
ByteArray holding allocated array w/length = allocated size.
Definition: byte_array.h:54
Kinetic object instance.
void KineticAllocator_FreeP2PProtobuf(Com__Seagate__Kinetic__Proto__Command__P2POperation *proto_p2pOp)
#define KINETIC_ASSERT(cond)
Com__Seagate__Kinetic__Proto__Command__Range * KineticResponse_GetKeyRange(KineticResponse *response)
KineticStatus KineticCallbacks_SetACL(KineticOperation *const operation, KineticStatus const status)
KineticStatus KineticCallbacks_GetKeyRange(KineticOperation *const operation, KineticStatus const status)
size_t len
Number of bytes in the data field.
Definition: byte_array.h:35
Com__Seagate__Kinetic__Proto__Command__Security__ACL ** ACLs
ACL struct array.
Device reported an operation error.
KineticStatus KineticCallbacks_P2POperation(KineticOperation *const operation, KineticStatus const status)
bool ByteBuffer_IsNull(ByteBuffer const buffer)
Definition: byte_array.c:249
ByteBuffer newVersion
New version for the object to assume once written to disk (optional)
uint8_t * data
Pointer to an allocated array of data bytes.
Definition: byte_array.h:36
#define BYTE_BUFFER_NONE
Convenience macro to represent an empty buffer with no data.
Definition: byte_array.h:65
KineticStatus KineticCallbacks_Basic(KineticOperation *const operation, KineticStatus const status)
KineticStatus KineticCallbacks_Put(KineticOperation *const operation, KineticStatus const status)
Status not available (no reponse/status available)
size_t ACL_count
How many ACL * structs are in ACLs[].
KineticStatus
Kinetic status codes.
static void populateP2PStatusCodes(KineticP2P_Operation *const p2pOp, Com__Seagate__Kinetic__Proto__Command__P2POperation const *const p2pOperation)
KineticStatus KineticCallbacks_SetClusterVersion(KineticOperation *const operation, KineticStatus const status)
size_t bytesUsed
Reflects the number of bytes used from the array
Definition: byte_array.h:55
KineticLogInfo * KineticLogInfo_Create(const Com__Seagate__Kinetic__Proto__Command__GetLog *getLog)
ByteBuffer dbVersion
Current version of the entry (optional)
KineticStatus KineticCallbacks_UpdateFirmware(KineticOperation *const operation, KineticStatus const status)
KineticStatus KineticCallbacks_GetLog(KineticOperation *const operation, KineticStatus const status)
bool Copy_Com__Seagate__Kinetic__Proto__Command__KeyValue_to_KineticEntry(Com__Seagate__Kinetic__Proto__Command__KeyValue *key_value, KineticEntry *entry)