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

com.github.sdmcraft.slingdynamo.impl.DynamoDBResourceProvider Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2013-14, Satya Deep Maheshwari. All rights reserved.
 *
 * The contents of this file are subject to the MIT License
 * You may not use this file except in compliance with the License.
 * A copy of the License is available at
 * http://opensource.org/licenses/MIT
 *
 * Copyright (c) 2013-2014 Satya Deep Maheshwari
 */
package com.github.sdmcraft.slingdynamo.impl;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.ItemCollection;
import com.amazonaws.services.dynamodbv2.document.ScanFilter;
import com.amazonaws.services.dynamodbv2.document.ScanOutcome;
import com.amazonaws.services.dynamodbv2.document.Table;
import com.amazonaws.services.dynamodbv2.model.DescribeTableRequest;
import com.amazonaws.services.dynamodbv2.model.DescribeTableResult;

import org.apache.sling.api.resource.ModifyingResourceProvider;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceProvider;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.wrappers.ModifiableValueMapDecorator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;


// TODO: Auto-generated Javadoc
/**
 * The Class DynamoDBResourceProvider.
 */
public class DynamoDBResourceProvider implements ResourceProvider,
    ModifyingResourceProvider {
    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDBResourceProvider.class);

    /** The dynamo db client. */
    private AmazonDynamoDBClient dynamoDBClient;

    /** The dynamo db. */
    private DynamoDB dynamoDB;

    /** The resource type. */
    private String resourceType;

    /** The root. */
    private String root;

    /**
     * Instantiates a new dynamo db resource provider.
     *
     * @param root the root
     * @param dynamoDBClient the dynamo db client
     * @param dynamoDB the dynamo db
     * @param resourceType the resource type
     */
    public DynamoDBResourceProvider(String root,
        AmazonDynamoDBClient dynamoDBClient, DynamoDB dynamoDB,
        String resourceType) {
        super();
        this.root = root;
        this.dynamoDBClient = dynamoDBClient;
        this.dynamoDB = dynamoDB;
        this.resourceType = resourceType;
    }

    /* (non-Javadoc)
     * @see org.apache.sling.api.resource.ModifyingResourceProvider#commit(org.apache.sling.api.resource.ResourceResolver)
     */
    public void commit(ResourceResolver arg0) throws PersistenceException {
        LOGGER.info(">>>>>>>>Commit");
    }

    /* (non-Javadoc)
     * @see org.apache.sling.api.resource.ModifyingResourceProvider#create(org.apache.sling.api.resource.ResourceResolver, java.lang.String, java.util.Map)
     */
    public Resource create(ResourceResolver arg0, String arg1,
        Map arg2) throws PersistenceException {
        throw new UnsupportedOperationException();
    }

    /* (non-Javadoc)
     * @see org.apache.sling.api.resource.ModifyingResourceProvider#delete(org.apache.sling.api.resource.ResourceResolver, java.lang.String)
     */
    public void delete(ResourceResolver arg0, String arg1)
        throws PersistenceException {
        throw new UnsupportedOperationException();
    }

    /**
     * Returns a resource from this resource provider or null if the resource provider cannot find it.
     * The table-name, id and child-ids are parsed out from the path and queried against dynamodb to fetch the specified resource.
     *
     * @param resolver the ResourceResolver to which the returned Resource is attached.
     * @param req the HttpServletRequest made to get this resource
     * @param path the path of the resource. The path is of the format <table-name>/<id>/[<child-id1>/.../<child-idn>]
     * @return the resource at the specified path if it exists else returns null
     */
    public Resource getResource(ResourceResolver resolver,
        HttpServletRequest req, String path) {
        Resource resource = null;

        try {
            Map resourceProps = new HashMap();
            ResourceMetadata resourceMetadata = new ResourceMetadata();
            resourceMetadata.setResolutionPath(path);

            if (!path.contains(".")) {
                if (path.length() > root.length()) {
                    String subPath = path.substring(root.length() + 1);
                    String[] subPathSplits = subPath.split("/");
                    String table = subPathSplits[0];
                    resourceMetadata.put("table", table);

                    Table dbtable = dynamoDB.getTable(table);

                    if (subPathSplits.length == 1) {
                        DescribeTableRequest describeTableRequest = new DescribeTableRequest(table);
                        DescribeTableResult describeTableResult = null;

                        describeTableResult = dynamoDBClient.describeTable(describeTableRequest);

                        Date creationDate = describeTableResult.getTable()
                                                               .getCreationDateTime();
                        long itemCount = describeTableResult.getTable()
                                                            .getItemCount();

                        resourceProps.put("creation-date", creationDate);
                        resourceProps.put("record-count", itemCount);
                        resourceProps.put("table-name", table);
                    } else if (subPathSplits.length == 2) {
                        int id = Integer.parseInt(subPathSplits[1]);
                        ScanFilter idFilter = new ScanFilter("id").eq(id);
                        ItemCollection items = dbtable.scan(idFilter);
                        Iterator itemItr = items.iterator();

                        Item item = itemItr.next();
                        resourceProps = itemToMap(item);
                    } else if (subPathSplits.length > 2) {
                        int parent = Integer.parseInt(subPathSplits[1]);
                        Item item = null;

                        for (int i = 2; i < subPathSplits.length; i++) {
                            int child = Integer.parseInt(subPathSplits[i]);
                            ScanFilter parentFilter = new ScanFilter("parent").eq(parent);
                            ScanFilter childFilter = new ScanFilter("child_id").eq(child);
                            ItemCollection items = dbtable.scan(parentFilter,
                                    childFilter);
                            Iterator itemItr = items.iterator();
                            item = itemItr.next();
                            parent = item.getInt("id");
                        }

                        resourceProps = itemToMap(item);
                    }
                }

                resourceProps.put("hello", "world");

                ModifiableValueMapDecorator valueMap = new ModifiableValueMapDecorator(resourceProps);

                resource = new DynamoDBResource(resolver, resourceMetadata,
                        valueMap, resourceType);
            }
        } catch (Throwable ex) {
            LOGGER.error(ex.getMessage(), ex);
            throw new RuntimeException(ex);
        }

        return resource;
    }

    /* (non-Javadoc)
     * @see org.apache.sling.api.resource.ResourceProvider#getResource(org.apache.sling.api.resource.ResourceResolver, java.lang.String)
     */
    public Resource getResource(ResourceResolver resolver, String path) {
        return getResource(resolver, null, path);
    }

    /* (non-Javadoc)
     * @see org.apache.sling.api.resource.ModifyingResourceProvider#hasChanges(org.apache.sling.api.resource.ResourceResolver)
     */
    public boolean hasChanges(ResourceResolver arg0) {
        LOGGER.info(">>>>>>>>HasChanges");

        return false;
    }

    /**
     *  Fetches the child resources of the specified resource by querying up dynamodb with the child-ids for this resource
     *
     * @param resource the resource whose children are to be fetched
     * @return the iterator over the child resources
     * @see org.apache.sling.api.resource.ResourceProvider#listChildren(org.apache.sling.api.resource.Resource)
     */
    public Iterator listChildren(Resource resource) {
        ValueMap parentValueMap = resource.adaptTo(ValueMap.class);

        if ((parentValueMap == null) ||
                !parentValueMap.containsKey("children") ||
                (parentValueMap.get("children") == null)) {
            return null;
        } else {
            Set children = parentValueMap.get("children", Set.class);
            Iterator childIdItr = children.iterator();

            Object[] childrenIdsArray = new Object[children.size()];
            int i = 0;

            while (childIdItr.hasNext()) {
                childrenIdsArray[i++] = childIdItr.next().intValue();
            }

            String tableS = (String) resource.getResourceMetadata().get("table");
            Table dbtable = dynamoDB.getTable(tableS);

            List childrenResourceList = getChildren(dbtable,
                    parentValueMap.get("id", Integer.class), childrenIdsArray,
                    resource.getResourceMetadata().getResolutionPath(),
                    resource.getResourceResolver());

            return childrenResourceList.iterator();
        }
    }

    /* (non-Javadoc)
     * @see org.apache.sling.api.resource.ModifyingResourceProvider#revert(org.apache.sling.api.resource.ResourceResolver)
     */
    public void revert(ResourceResolver arg0) {
        LOGGER.info(">>>>>>>>Revert");
    }

    /**
     * Gets the children.
     *
     * @param dbtable the dbtable
     * @param parent the parent
     * @param childIds the child ids
     * @param path the path
     * @param resolver the resolver
     * @return the children
     */
    private List getChildren(Table dbtable, int parent,
        Object[] childIds, String path, ResourceResolver resolver) {
        ScanFilter idFilter = new ScanFilter("parent").in(parent);
        ScanFilter childIdsFilter = new ScanFilter("child_id").in(childIds);
        ItemCollection items = dbtable.scan(idFilter,
                childIdsFilter);
        Iterator itemItr = items.iterator();
        List children = new ArrayList();

        while (itemItr.hasNext()) {
            Item item = itemItr.next();
            Iterable> attributes = item.attributes();
            Iterator> attributesItr = attributes.iterator();
            Map resourceProps = new HashMap();

            while (attributesItr.hasNext()) {
                Entry attribute = attributesItr.next();
                resourceProps.put(attribute.getKey(), attribute.getValue());
            }

            ModifiableValueMapDecorator valueMap = new ModifiableValueMapDecorator(resourceProps);
            ResourceMetadata resourceMetadata = new ResourceMetadata();
            resourceMetadata.setResolutionPath(path + '/' +
                resourceProps.get("child_id"));
            resourceMetadata.put("table", dbtable.getTableName());

            children.add(new DynamoDBResource(resolver, resourceMetadata,
                    valueMap, resourceType));
        }

        return children;
    }

    /**
     * Item to map.
     *
     * @param item the item
     * @return the map
     */
    private Map itemToMap(Item item) {
        Map resourceProps = new HashMap();
        Iterable> attributes = item.attributes();
        Iterator> attributesItr = attributes.iterator();

        while (attributesItr.hasNext()) {
            Entry attribute = attributesItr.next();
            resourceProps.put(attribute.getKey(), attribute.getValue());
        }

        return resourceProps;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy