001/**
002 * Copyright 2016 Tampere University of Technology, Pori Department
003 * 
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * 
008 *   http://www.apache.org/licenses/LICENSE-2.0
009 * 
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package service.tut.pori.apilta.files;
017
018import java.io.IOException;
019import java.io.InputStream;
020import java.util.HashMap;
021import java.util.Map;
022import java.util.UUID;
023
024import org.apache.log4j.Logger;
025import org.jclouds.io.Payload;
026import org.jclouds.io.Payloads;
027import org.jclouds.openstack.swift.v1.domain.SwiftObject;
028import org.springframework.beans.factory.DisposableBean;
029
030import core.tut.pori.dao.DAO;
031import service.tut.pori.apilta.files.datatypes.FileDetails;
032import service.tut.pori.apilta.files.datatypes.SignedURL;
033
034/**
035 * Content storage driver for accessing OpenStack Swift Object Storage.
036 */
037public class FileDAO implements DAO, DisposableBean {
038  private static final Logger LOGGER = Logger.getLogger(FileDAO.class);
039  private static final String METADATA_MIME_TYPE = "mimeType";
040  private SwiftTemplate _swiftTemplate = null;
041  
042  /**
043   * 
044   */
045  public FileDAO() {
046    _swiftTemplate = new SwiftTemplate();
047  }
048  
049  /**
050   * 
051   * @param file
052   * @return guid of the created file or null on failure
053   */
054  public String addFile(InputStream file) {
055    String guid = UUID.randomUUID().toString();
056    try(Payload payload = Payloads.newInputStreamPayload(file)){      
057      _swiftTemplate.put(guid, payload);
058    } catch (IOException ex) {
059      LOGGER.error(ex, ex);
060      return null;
061    }
062    return guid;
063  }
064  
065  /**
066   * 
067   * @param details
068   * @return true on success
069   */
070  public boolean updateFile(FileDetails details) {
071    HashMap<String, String> metadata = new HashMap<>(1);
072    metadata.put(METADATA_MIME_TYPE, details.getMimeType());
073    _swiftTemplate.update(details.getGUID(), metadata); // TODO how to know if this has succeeded?
074    return true;
075  }
076
077  /**
078   * 
079   * @param guid
080   * @return file details for the content or null if no content matching the guid was found
081   */
082  public FileDetails getFileDetails(String guid) {
083    SwiftObject object = _swiftTemplate.get(guid);
084    if(object == null){
085      LOGGER.debug("Could not find object for guid: "+guid);
086      return null;
087    }
088    
089    FileDetails details = new FileDetails();
090    details.setGUID(guid);
091    Map<String, String> metadata = object.getMetadata();
092    details.setMimeType(metadata.get(METADATA_MIME_TYPE));
093    SignedURL signedURL = _swiftTemplate.signURL(object);
094    details.setUrl(signedURL.getUrl());
095    details.setValidUntil(signedURL.getValidUntil());
096    return details; // the only metadata that is currently used
097  }
098
099  /**
100   * 
101   * @param guid
102   */
103  public void removeFile(String guid) {
104    _swiftTemplate.delete(guid);
105  }
106
107  @Override
108  public void destroy() { 
109    _swiftTemplate.close();
110    _swiftTemplate = null;
111  }
112}