Package com.netflix.priam.aws

Source Code of com.netflix.priam.aws.S3PrefixIterator

/**
* Copyright 2013 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.netflix.priam.aws;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.ListObjectsRequest;
import com.amazonaws.services.s3.model.ObjectListing;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.netflix.priam.IConfiguration;
import com.netflix.priam.backup.AbstractBackupPath;

/**
* Class to iterate over prefixes (S3 Common prefixes) upto
* the token element in the path. The abstract path generated by this class
* is partial (does not have all data).
*/
public class S3PrefixIterator implements Iterator<AbstractBackupPath>
{
    private static final Logger logger = LoggerFactory.getLogger(S3PrefixIterator.class);
    private final IConfiguration config;
    private final AmazonS3 s3Client;
    private final Provider<AbstractBackupPath> pathProvider;
    private Iterator<AbstractBackupPath> iterator;
   
    private String bucket = "";
    private String clusterPath = "";
    private SimpleDateFormat datefmt = new SimpleDateFormat("yyyyMMdd");
    private ObjectListing objectListing;
    Date date;

    @Inject
    public S3PrefixIterator(IConfiguration config, Provider<AbstractBackupPath> pathProvider, AmazonS3 s3Client, Date date)
    {
        this.config = config;
        this.pathProvider = pathProvider;
        this.s3Client = s3Client;
        this.date = date;
        String path = "";
        if (StringUtils.isNotBlank(config.getRestorePrefix()))
            path = config.getRestorePrefix();
        else
            path = config.getBackupPrefix();

        String[] paths = path.split(String.valueOf(S3BackupPath.PATH_SEP));
        bucket = paths[0];
        this.clusterPath = remotePrefix(path);
        objectListing = null;
        iterator = createIterator();
    }

    private void initListing()
    {
        ListObjectsRequest listReq = new ListObjectsRequest();
        // Get list of tokens
        listReq.setBucketName(bucket);
        listReq.setPrefix(clusterPath);
        listReq.setDelimiter(String.valueOf(AbstractBackupPath.PATH_SEP));
        logger.info("Using cluster prefix for searching tokens: " + clusterPath);
        objectListing = s3Client.listObjects(listReq);

    }

    private Iterator<AbstractBackupPath> createIterator()
    {
        if (objectListing == null)
            initListing();
        List<AbstractBackupPath> temp = Lists.newArrayList();
        for (String summary : objectListing.getCommonPrefixes())
        {
            if (pathExistsForDate(summary, datefmt.format(date)))
            {
                AbstractBackupPath path = pathProvider.get();
                path.parsePartialPrefix(summary);
                temp.add(path);
            }
        }
        return temp.iterator();
    }

    @Override
    public boolean hasNext()
    {
        if (iterator.hasNext())
        {
            return true;
        }
        else
        {
            while (objectListing.isTruncated() && !iterator.hasNext())
            {
                objectListing = s3Client.listNextBatchOfObjects(objectListing);
                iterator = createIterator();
            }
        }
        return iterator.hasNext();
    }

    @Override
    public AbstractBackupPath next()
    {
        return iterator.next();
    }

    @Override
    public void remove()
    {
    }

    /**
     * Get remote prefix upto the token
     */
    private String remotePrefix(String location)
    {
        StringBuffer buff = new StringBuffer();
        String[] elements = location.split(String.valueOf(S3BackupPath.PATH_SEP));
        if (elements.length <= 1)
        {
            buff.append(config.getBackupLocation()).append(S3BackupPath.PATH_SEP);
            buff.append(config.getDC()).append(S3BackupPath.PATH_SEP);
            buff.append(config.getAppName()).append(S3BackupPath.PATH_SEP);
        }
        else
        {
            assert elements.length >= 4 : "Too few elements in path " + location;
            buff.append(elements[1]).append(S3BackupPath.PATH_SEP);
            buff.append(elements[2]).append(S3BackupPath.PATH_SEP);
            buff.append(elements[3]).append(S3BackupPath.PATH_SEP);
        }
        return buff.toString();
    }

    /**
     * Check to see if the path exists for the date
     */
    private boolean pathExistsForDate(String tprefix, String datestr)
    {
        ListObjectsRequest listReq = new ListObjectsRequest();
        // Get list of tokens
        listReq.setBucketName(bucket);
        listReq.setPrefix(tprefix + datestr);
        ObjectListing listing;
        listing = s3Client.listObjects(listReq);
        if (listing.getObjectSummaries().size() > 0)
            return true;
        return false;
    }

}
TOP

Related Classes of com.netflix.priam.aws.S3PrefixIterator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.