All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.qmetric.feed.consumer.store.SimpleDBConsumedStore Maven / Gradle / Ivy

package com.qmetric.feed.consumer.store;

import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.simpledb.AmazonSimpleDB;
import com.amazonaws.services.simpledb.model.Attribute;
import com.amazonaws.services.simpledb.model.CreateDomainRequest;
import com.amazonaws.services.simpledb.model.DeleteAttributesRequest;
import com.amazonaws.services.simpledb.model.DomainMetadataRequest;
import com.amazonaws.services.simpledb.model.Item;
import com.amazonaws.services.simpledb.model.PutAttributesRequest;
import com.amazonaws.services.simpledb.model.ReplaceableAttribute;
import com.amazonaws.services.simpledb.model.SelectRequest;
import com.amazonaws.services.simpledb.model.UpdateCondition;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.theoryinpractise.halbuilder.api.ReadableRepresentation;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import static com.google.common.collect.FluentIterable.from;
import static java.lang.String.format;
import static org.joda.time.DateTime.now;

public class SimpleDBConsumedStore implements ConsumedStore
{
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormat.forPattern("yyyy/MM/dd HH:mm:ss");

    private static final String CONDITIONAL_CHECK_FAILED_ERROR_CODE = "ConditionalCheckFailed";

    private static final String ID_PROPERTY = "_id";

    private static final String CONSUMED_DATE_ATTR = "consumed";

    private static final String CONSUMING_DATE_ATTR = "consuming";

    private static final String SELECT_CONSUMED_ITEM = "select itemName() from `%s` where itemName() = '%s' and `%s` is not null limit 1";

    private final AmazonSimpleDB simpleDBClient;

    private final String domain;

    public SimpleDBConsumedStore(final AmazonSimpleDB simpleDBClient, final String domain)
    {
        this.simpleDBClient = simpleDBClient;
        this.domain = domain;

        simpleDBClient.createDomain(new CreateDomainRequest(domain));
    }

    @Override public void checkConnectivity() throws ConnectivityException
    {
        try
        {
            simpleDBClient.domainMetadata(new DomainMetadataRequest(domain));
        }
        catch (final Exception e)
        {
            throw new ConnectivityException(e);
        }
    }

    @Override public void markAsConsuming(final ReadableRepresentation feedEntry) throws AlreadyConsumingException
    {
        final UpdateCondition onlyIfNotAlreadyConsuming = new UpdateCondition().withName(CONSUMING_DATE_ATTR).withExists(false);

        try
        {
            simpleDBClient.putAttributes(new PutAttributesRequest(domain, getId(feedEntry), ImmutableList
                    .of(new ReplaceableAttribute().withName(CONSUMING_DATE_ATTR).withValue(DATE_FORMATTER.print(now())).withReplace(true)), onlyIfNotAlreadyConsuming));
        }
        catch (final AmazonServiceException e)
        {
            if (CONDITIONAL_CHECK_FAILED_ERROR_CODE.equalsIgnoreCase(e.getErrorCode()))
            {
                throw new AlreadyConsumingException(e);
            }
            else
            {
                throw e;
            }
        }
    }

    @Override public void revertConsuming(final ReadableRepresentation feedEntry)
    {
        simpleDBClient.deleteAttributes(new DeleteAttributesRequest(domain, getId(feedEntry), ImmutableList.of(new Attribute().withName(CONSUMING_DATE_ATTR))));
    }

    @Override public void markAsConsumed(final ReadableRepresentation feedEntry)
    {
        simpleDBClient.putAttributes(new PutAttributesRequest(domain, getId(feedEntry), ImmutableList
                .of(new ReplaceableAttribute().withName(CONSUMED_DATE_ATTR).withValue(DATE_FORMATTER.print(now())).withReplace(true))));
    }

    @Override public boolean notAlreadyConsumed(final ReadableRepresentation feedEntry)
    {
        final SelectRequest request = new SelectRequest().withSelectExpression(format(SELECT_CONSUMED_ITEM, domain, getId(feedEntry), CONSUMED_DATE_ATTR)).withConsistentRead(true);

        final Optional consumedEntry = from(simpleDBClient.select(request).getItems()).first();

        return !consumedEntry.isPresent();
    }

    private String getId(final ReadableRepresentation feedEntry)
    {
        return (String) feedEntry.getValue(ID_PROPERTY);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy