com.vitembp.embedded.data.UuidStringStoreDynamoDB.java Source code

Java tutorial

Introduction

Here is the source code for com.vitembp.embedded.data.UuidStringStoreDynamoDB.java

Source

/*
 * Video Telemetry for Mountain Bike Platform back-end services.
 * Copyright (C) 2017 Kyle Grund
 *
 * 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 3 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, see <http://www.gnu.org/licenses/>.
 */
package com.vitembp.embedded.data;

import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.DeleteItemRequest;
import com.amazonaws.services.dynamodbv2.model.DeleteItemResult;
import com.amazonaws.services.dynamodbv2.model.GetItemRequest;
import com.amazonaws.services.dynamodbv2.model.GetItemResult;
import com.amazonaws.services.dynamodbv2.model.ResourceNotFoundException;
import com.amazonaws.services.dynamodbv2.model.ReturnItemCollectionMetrics;
import com.amazonaws.services.dynamodbv2.model.ScanRequest;
import com.amazonaws.services.dynamodbv2.model.ScanResult;
import com.vitembp.embedded.configuration.SystemConfig;
import java.io.IOException;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Stream;
import org.apache.logging.log4j.LogManager;

/**
 * Creates a UuidStringStore for the H2 embedded database.
 */
class UuidStringStoreDynamoDB implements UuidStringStore {
    /**
     * Class logger instance.
     */
    private static final org.apache.logging.log4j.Logger LOGGER = LogManager.getLogger();

    /**
     * The connection to the database.
     */
    private final AmazonDynamoDB client;

    /**
     * Initializes a new instance of the UuidStringStoreH2 class.
     * @param dataFile The file to store the database to.
     */
    UuidStringStoreDynamoDB() {
        // builds a client with credentials
        this.client = AmazonDynamoDBClient.builder().build();
    }

    @Override
    public Stream<CaptureDescription> getCaptureLocations() throws IOException {
        List<ScanResult> keys = new ArrayList<>();
        List<String> params = Arrays.asList(new String[] { "LOCATION", "SYSTEM_UUID", "CREATEDTIME", "FREQUENCY" });
        ScanResult res = this.client.scan("CAPTURES", params);
        keys.add(res);
        Map<String, AttributeValue> lastRes = res.getLastEvaluatedKey();
        while (lastRes != null) {
            ScanRequest sr = new ScanRequest();
            sr.setTableName("CAPTURES");
            sr.setAttributesToGet(params);
            sr.setExclusiveStartKey(lastRes);
            res = this.client.scan(sr);
            keys.add(res);
            lastRes = res.getLastEvaluatedKey();
        }
        // return results as stream of captures
        return res.getItems().stream()
                .map((item) -> new CaptureDescription(UUID.fromString(item.get("LOCATION").getS()),
                        UUID.fromString(item.get("SYSTEM_UUID").getS()),
                        Instant.parse(item.get("CREATEDTIME").getS()),
                        Double.parseDouble(item.get("FREQUENCY").getS())));
    }

    @Override
    public void addCaptureDescription(CaptureDescription toAdd) throws IOException {
        // add capture data: location, system, start, frequency to captures table
        Map<String, AttributeValue> attrs = new HashMap<>();
        attrs.put("LOCATION", new AttributeValue(toAdd.getLocation().toString()));
        attrs.put("SYSTEM_UUID", new AttributeValue(SystemConfig.getConfig().getSystemUUID().toString()));
        attrs.put("CREATEDTIME", new AttributeValue(toAdd.getCreated().toString()));
        attrs.put("FREQUENCY", new AttributeValue(Double.toString(toAdd.getFrequency())));

        try {
            this.client.putItem("CAPTURES", attrs);
        } catch (ResourceNotFoundException e) {
            LOGGER.error("The database does not contain the captures index table.", e);
        } catch (AmazonServiceException e) {
            LOGGER.error("Exception occurred writing to database.", e);
        }
    }

    @Override
    public CaptureDescription getCaptureDescription(UUID location) throws IOException {
        Map<String, AttributeValue> reqkey = new HashMap<>();
        reqkey.put("LOCATION", new AttributeValue().withS(location.toString()));
        List<String> params = Arrays.asList(new String[] { "SYSTEM_UUID", "CREATEDTIME", "FREQUENCY" });

        GetItemRequest request = new GetItemRequest().withTableName("CAPTURES").withKey(reqkey)
                .withAttributesToGet(params);

        GetItemResult result = client.getItem(request);
        if (result != null && result.getItem() != null) {
            UUID system = UUID.fromString(result.getItem().get("SYSTEM_UUID").getS());
            Instant time = Instant.parse(result.getItem().get("CREATEDTIME").getS());
            double frequency = Double.parseDouble(result.getItem().get("FREQUENCY").getS());
            return new CaptureDescription(location, system, time, frequency);
        } else {
            // no items returned, so return null
            return null;
        }
    }

    @Override
    public String read(UUID key) throws IOException {
        Map<String, AttributeValue> reqkey = new HashMap<>();
        reqkey.put("ID", new AttributeValue().withS(key.toString()));

        GetItemRequest request = new GetItemRequest().withTableName("DATA").withKey(reqkey);

        GetItemResult result = client.getItem(request);
        if (result != null && result.getItem() != null) {
            AttributeValue val = result.getItem().get("VALUE");
            return val.getS();
        } else {
            // no items returned, so return null
            return null;
        }
    }

    @Override
    public void write(UUID key, String value) throws IOException {
        Map<String, AttributeValue> toAdd = new HashMap<>();
        toAdd.put("ID", new AttributeValue(key.toString()));
        toAdd.put("VALUE", new AttributeValue(value));

        try {
            this.client.putItem("DATA", toAdd);
        } catch (ResourceNotFoundException e) {
            LOGGER.error("The database does not contain the data table.", e);
        } catch (AmazonServiceException e) {
            LOGGER.error("Exception occurred writing to database.", e);
        }
    }

    @Override
    public void delete(UUID key) throws IOException {
        Map<String, AttributeValue> reqkey = new HashMap<>();
        reqkey.put("ID", new AttributeValue().withS(key.toString()));

        DeleteItemRequest request = new DeleteItemRequest().withTableName("DATA").withKey(reqkey)
                .withReturnItemCollectionMetrics(ReturnItemCollectionMetrics.SIZE);

        DeleteItemResult result = client.deleteItem(request);
    }

    @Override
    public Stream<UUID> getKeys() throws IOException {
        List<ScanResult> keys = new ArrayList<>();
        ScanResult res = this.client.scan("DATA", Arrays.asList(new String[] { "ID" }));
        keys.add(res);
        Map<String, AttributeValue> lastRes = res.getLastEvaluatedKey();
        while (lastRes != null) {
            ScanRequest sr = new ScanRequest();
            sr.setTableName("DATA");
            sr.setAttributesToGet(Arrays.asList(new String[] { "ID" }));
            sr.setExclusiveStartKey(lastRes);
            res = this.client.scan(sr);
            keys.add(res);
            lastRes = res.getLastEvaluatedKey();
        }
        return res.getItems().stream().map((item) -> UUID.fromString(item.get("ID").getS()));
    }

    @Override
    public Map<UUID, String> getHashes(List<UUID> locations) throws IOException {
        Map<UUID, String> hashes = new HashMap<>();
        for (UUID loc : locations) {
            // try to get any data
            String toHash = this.read(loc);
            if (toHash == null) {
                // put in an empty string as this entry is blank
                hashes.put(loc, "");
            } else {
                // had data, add the standard 32bit string hash
                hashes.put(loc, Integer.toString(toHash.hashCode()));
            }
        }
        return hashes;
    }

    @Override
    public void removeCaptureDescription(UUID location) throws IOException {
        Map<String, AttributeValue> attrs = new HashMap<>();
        attrs.put("LOCATION", new AttributeValue(location.toString()));
        DeleteItemRequest request = new DeleteItemRequest().withTableName("CAPTURES").withKey(attrs);
        DeleteItemResult result = client.deleteItem(request);
    }
}