Commit 82b830f2 authored by Greg Williams's avatar Greg Williams
Browse files

Started implementation of async IO system test.

Added examples/ folder with stubbed source files for standalone examples for various PUT/write use cases
parent c5c8f7fd
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -283,3 +283,29 @@ run: $(UTIL_EXEC) start_simulator
	@echo
	@echo Stopping simulator...
	./vendor/kinetic-simulator/stopSimulator.sh


#===============================================================================
# Standalone Example Executables
#===============================================================================

# EXAMPLE_SRC = ./src/examples
# EXAMPLE_BIN = $(BIN_DIR)/
# EXAMPLE_LDFLAGS += -lm -l ssl $(KINETIC_LIB) -l crypto -l pthread

# $(OUT_DIR)/%.o: %.c $(DEPS)
# 	$(CC) -c -o $@ $< $(CFLAGS)

# $(UTIL_OBJ): $(EXAMPLE_SRC)/*.c
# 	$(CC) -c -o $@ $< $(CFLAGS) -I$(PUB_INC)

# $(UTIL_EXEC): $(UTIL_OBJ) $(KINETIC_LIB)
# 	@echo
# 	@echo --------------------------------------------------------------------------------
# 	@echo Building development test utility: $(UTIL_EXEC)
# 	@echo --------------------------------------------------------------------------------
# 	$(CC) -o $@ $< $(CFLAGS) $(UTIL_LDFLAGS) $(KINETIC_LIB)

# utility: $(UTIL_EXEC)

# build: $(KINETIC_LIB) $(KINETIC_SO_DEV) utility
+2 −2
Original line number Diff line number Diff line
@@ -64,8 +64,8 @@ Example Client/Test Utility

Code examples are included for reference as part of a test utility. The source code for the utility is used to build both a static and dynamically linked verion of the kinetic-c-client library.

* 'kinetic-c-util' builds/links against installed Kinetic C static library (.a)
* 'kinetic-c-util.x.y.z' builds/links against installed Kinetic C dynamic library (.so)
* `kinetic-c-util` builds/links against Kinetic C static library (.a)
* `kinetic-c-util.x.y.z` builds/links against Kinetic C dynamic library (.so)

The project Makefile can be used as a reference for developing a Makefile for building for a new custom Kinetic C client.

src/examples/README.md

0 → 100644
+7 −0
Original line number Diff line number Diff line
Kinetic C Client Examples
=========================

* `write_file_blocking` - Single thread, single connection sync operation.
* `write_file_blocking_threads` - Multiple threads, single connection, sync operations.
* `write_file_nonblocking` - Single thread, single connection, multiple async operations
* `write_file_blocking_threads` - Multiple threads, single connection, multiple async operations.
+143 −0
Original line number Diff line number Diff line
/*
* kinetic-c
* Copyright (C) 2014 Seagate Technology.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/

#include "kinetic_client.h"
#include "kinetic_types.h"
#include "byte_array.h"

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/stat.h>

typedef struct {
    char ip[16];
    KineticSessionHandle sessionHandle;
    char keyPrefix[KINETIC_DEFAULT_KEY_LEN];
    uint8_t key[KINETIC_DEFAULT_KEY_LEN];
    uint8_t version[KINETIC_DEFAULT_KEY_LEN];
    uint8_t tag[KINETIC_DEFAULT_KEY_LEN];
    uint8_t value[KINETIC_OBJ_SIZE];
    KineticEntry entry;
    ByteBuffer data;
    KineticStatus status;
} write_args;
static write_args WriteArgs;

void kinetic_put(write_args* args)
{
    KineticEntry* entry = &(args->entry);
    int32_t objIndex = 0;

    while (ByteBuffer_BytesRemaining(args->data) > 0) {

        // Configure entry meta-data
        ByteBuffer_Reset(&entry->key);
        ByteBuffer_AppendCString(&entry->key, WriteArgs.keyPrefix);
        char keySuffix[8];
        snprintf(keySuffix, sizeof(keySuffix), "%02d", objIndex);
        ByteBuffer_AppendCString(&entry->key, keySuffix);

        // Prepare entry with the next object to store
        ByteBuffer_Reset(&entry->value);
        ByteBuffer_AppendArray(
            &entry->value,
            ByteBuffer_Consume(
                &args->data,
                MIN(ByteBuffer_BytesRemaining(args->data), KINETIC_OBJ_SIZE))
        );

        // Store the object
        KineticStatus status = KineticClient_Put(args->sessionHandle, entry, NULL);
        if (status != KINETIC_STATUS_SUCCESS) {
            fprintf(stderr, "Kinetic PUT of object %d to host %s failed w/ status: %s\n",
                objIndex, args->ip, Kinetic_GetStatusDescription(status));
            exit(-1);
        }

        objIndex++;
    }

    printf("File stored on Kinetic Device across %d entries\n", objIndex);
}

int main(const char * argc, const int argv)
{
    KineticSessionHandle kinetic_client;
    const char HmacKeyString[] = "asdfasdf";
    const KineticSession sessionConfig = {
        .host = "localhost",
        .port = KINETIC_PORT,
        .clusterVersion = 0,
        .identity = 1,
        .nonBlocking = false,
        .hmacKey = ByteArray_CreateWithCString(HmacKeyString),
    };

    // Read in file contents to store
    const char* dataFile = "test/support/data/test.data";
    struct stat st;
    stat(dataFile, &st);
    char* buf = malloc(st.st_size);
    int fd = open(dataFile, O_RDONLY);
    long dataLen = read(fd, buf, BUFSIZE);
    close(fd);
    if (dataLen <= 0) {
        fprinf(stderr, "Failed reading data file to store: %s", dataFile);
        exit(-1);
    }

    // Establish connection
    KineticClient_Connect(&sessionConfig, &kinetic_client));

    // Create a ByteBuffer for consuming chunks of data out of for overlapped PUTs
    WriteArgs.data = ByteBuffer_Create(buf, dataLen, 0);

    // Configure common meta-data for the entries
    struct timeval now;
    gettimeofday(&now, NULL);
    snprintf(WriteArgs.keyPrefix, sizeof(WriteArgs.keyPrefix), "%010llu_%02d%02d_",
        now.tv_sec, iteration, i);
    ByteBuffer verBuf = ByteBuffer_Create(WriteArgs.version, sizeof(WriteArgs.version), 0);
    ByteBuffer_AppendCString(&verBuf, "v1.0");
    ByteBuffer tagBuf = ByteBuffer_Create(WriteArgs.tag, sizeof(WriteArgs.tag), 0);
    ByteBuffer_AppendCString(&tagBuf, "some_value_tag...");
    WriteArgs.entry = (KineticEntry) {
        .key = ByteBuffer_Create(WriteArgs.key, sizeof(WriteArgs.key), 0),
        // .newVersion = verBuf,
        .tag = tagBuf,
        .algorithm = KINETIC_ALGORITHM_SHA1,
        .value = ByteBuffer valBuf = ByteBuffer_Create(WriteArgs.value, sizeof(WriteArgs.value), 0),
        .synchronization = KINETIC_SYNCHRONIZATION_WRITEBACK,
    };
    strcpy(WriteArgs.ip, sessionConfig.host);

    // Store the data
    printf("\nWriting data file to the Kinetic device...\n");
    kinetic_put(WriteArgs);

    // Shutdown client connection and cleanup
    KineticClient_Disconnect(&kinetic_client[i]);
    free(kinetic_client);
    free(kt_arg);
    free(buf);
}
+0 −0

Empty file added.

Loading