Skip to content
This repository has been archived by the owner on Jul 25, 2018. It is now read-only.

Commit

Permalink
feat(rest): new endpoints to upload and download attachments
Browse files Browse the repository at this point in the history
- Introduce AttachmentFrontendUtils
- Add attachment download endpoints for rest
- Add attachment upload endpoints for rest

Signed-off-by: Maximilian Huber <external.maximilian.huber2@bosch-si.com>
  • Loading branch information
maxhbr authored and Onur Demirci committed Mar 14, 2018
1 parent 354ffbd commit 62f0299
Show file tree
Hide file tree
Showing 14 changed files with 628 additions and 84 deletions.
Expand Up @@ -16,15 +16,13 @@
import com.liferay.portal.util.PortalUtil;
import org.apache.log4j.Logger;
import org.apache.thrift.TException;
import org.eclipse.sw360.commonIO.AttachmentFrontendUtils;
import org.eclipse.sw360.datahandler.common.CommonUtils;
import org.eclipse.sw360.datahandler.common.Duration;
import org.eclipse.sw360.datahandler.couchdb.AttachmentStreamConnector;
import org.eclipse.sw360.datahandler.thrift.RequestStatus;
import org.eclipse.sw360.datahandler.thrift.SW360Exception;
import org.eclipse.sw360.datahandler.thrift.ThriftClients;
import org.eclipse.sw360.datahandler.thrift.attachments.Attachment;
import org.eclipse.sw360.datahandler.thrift.attachments.AttachmentContent;
import org.eclipse.sw360.datahandler.thrift.attachments.AttachmentService;
import org.eclipse.sw360.datahandler.thrift.components.ComponentService;
import org.eclipse.sw360.datahandler.thrift.projects.ProjectService;
import org.eclipse.sw360.datahandler.thrift.users.User;
Expand All @@ -37,9 +35,7 @@

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.google.common.base.Strings.isNullOrEmpty;
Expand All @@ -54,56 +50,23 @@
* @author daniele.fognini@tngtech.com
* @author birgit.heydenreich@tngtech.com
*/
public class AttachmentPortletUtils {
public class AttachmentPortletUtils extends AttachmentFrontendUtils {
public static final String DEFAULT_ATTACHMENT_BUNDLE_NAME = "AttachmentBundle.zip";

private static final Logger log = Logger.getLogger(AttachmentPortletUtils.class);
private final ThriftClients thriftClients;
private final AttachmentService.Iface client;
private final ProjectService.Iface projectClient;
private final ComponentService.Iface componentClient;

private AttachmentStreamConnector connector;
// TODO add Config class and DI
private final Duration downloadTimeout = Duration.durationOf(30, TimeUnit.SECONDS);

public AttachmentPortletUtils() {
this(new ThriftClients());
}

public AttachmentPortletUtils(ThriftClients thriftClients) {
this.thriftClients = thriftClients;
client = thriftClients.makeAttachmentClient();
super(thriftClients);
projectClient = thriftClients.makeProjectClient();
componentClient = thriftClients.makeComponentClient();
}

private synchronized void makeConnector() throws TException {
if (connector == null) {
try {
connector = new AttachmentStreamConnector(downloadTimeout);
} catch (MalformedURLException e) {
log.error("Invalid database address received...", e);
throw new TException(e);
}
}
}

private AttachmentStreamConnector getConnector() throws TException {
if (connector == null) makeConnector();
return connector;
}

protected InputStream getStreamToServeAFile(List<AttachmentContent> attachments, User user, Object context) throws TException, IOException {
if(attachments == null || attachments.size() == 0){
throw new SW360Exception("Tried to download empty set of Attachments");
}else if(attachments.size() == 1){
return getConnector().getAttachmentStream(attachments.get(0), user, context);
} else {
return getConnector().getAttachmentBundleStream(new HashSet<>(attachments), user, context);
}
}

public void serveFile(ResourceRequest request, ResourceResponse response) {
serveFile(request, response, Optional.empty());
}
Expand Down Expand Up @@ -160,7 +123,7 @@ public void serveAttachmentBundle(List<AttachmentContent> attachments, ResourceR
serveAttachmentBundle(attachments, request, response, Optional.empty());
}

public void serveAttachmentBundle(List<AttachmentContent> attachments, ResourceRequest request, ResourceResponse response, Optional<String> downloadFileName){
private void serveAttachmentBundle(List<AttachmentContent> attachments, ResourceRequest request, ResourceResponse response, Optional<String> downloadFileName){
String filename;
String contentType;
if(attachments.size() == 1){
Expand Down Expand Up @@ -201,7 +164,7 @@ public void serveAttachmentBundle(List<AttachmentContent> attachments, ResourceR
}
}

public boolean uploadAttachmentPartFromRequest(PortletRequest request, String fileUploadName) throws IOException, TException {
private boolean uploadAttachmentPartFromRequest(PortletRequest request, String fileUploadName) throws IOException, TException {
final UploadPortletRequest uploadPortletRequest = PortalUtil.getUploadPortletRequest(request);
final InputStream stream = uploadPortletRequest.getFileAsStream(fileUploadName);

Expand Down Expand Up @@ -264,7 +227,6 @@ private AttachmentContent getAttachmentContent(ResumableUpload resumableUpload)
AttachmentContent attachment = null;
if (resumableUpload.hasAttachmentId()) {
try {
AttachmentService.Iface client = thriftClients.makeAttachmentClient();
attachment = client.getAttachmentContent(resumableUpload.getAttachmentId());
} catch (TException e) {
log.error("Error retrieving attachment", e);
Expand All @@ -273,25 +235,13 @@ private AttachmentContent getAttachmentContent(ResumableUpload resumableUpload)
return attachment;
}

private AttachmentContent updateAttachmentContent(AttachmentContent attachment) throws TException {
try {
AttachmentService.Iface client = thriftClients.makeAttachmentClient();
client.updateAttachmentContent(attachment);
} catch (SW360Exception e) {
log.error("Error updating attachment", e);
return null;
}
return attachment;
}

public AttachmentContent createAttachmentContent(ResourceRequest request) throws IOException {
String filename = request.getParameter("fileName");
AttachmentContent attachmentContent = new AttachmentContent()
.setContentType("application/octet-stream")
.setFilename(filename);

try {
AttachmentService.Iface client = thriftClients.makeAttachmentClient();
attachmentContent = client.makeAttachmentContent(attachmentContent);
} catch (TException e) {
log.error("Error creating attachment", e);
Expand All @@ -313,7 +263,6 @@ public boolean uploadAttachmentPart(PortletRequest request, String fileUploadNam
public RequestStatus cancelUpload(ResourceRequest request) {
String attachmentId = request.getParameter(PortalConstants.ATTACHMENT_ID);
try {
AttachmentService.Iface client = thriftClients.makeAttachmentClient();
return client.deleteAttachmentContent(attachmentId);
} catch (TException e) {
log.error("Error deleting attachment from backend", e);
Expand Down Expand Up @@ -352,24 +301,4 @@ private boolean alreadyHavePart(AttachmentContent attachment, ResumableUpload re
return false;
}
}

public Attachment getAttachmentForDisplay(User user, String attachmentContentId) {
try {
String filename = client.getAttachmentContent(attachmentContentId).getFilename();
return CommonUtils.getNewAttachment(user, attachmentContentId, filename);
} catch (TException e) {
log.error("Could not get attachment content", e);
}
return null;
}

public void deleteAttachments(Set<String> attachmentContentIds){
try {
for(String id: attachmentContentIds) {
client.deleteAttachmentContent(id);
}
} catch (TException e){
log.error("Could not delete attachments from database.",e);
}
}
}
@@ -0,0 +1,130 @@
/*
* Copyright Bosch Software Innovations GmbH, 2018.
* Part of the SW360 Portal Project.
*
* SPDX-License-Identifier: EPL-1.0
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.sw360.commonIO;

import org.apache.log4j.Logger;
import org.apache.thrift.TException;
import org.eclipse.sw360.datahandler.common.CommonUtils;
import org.eclipse.sw360.datahandler.common.Duration;
import org.eclipse.sw360.datahandler.couchdb.AttachmentStreamConnector;
import org.eclipse.sw360.datahandler.thrift.SW360Exception;
import org.eclipse.sw360.datahandler.thrift.ThriftClients;
import org.eclipse.sw360.datahandler.thrift.attachments.Attachment;
import org.eclipse.sw360.datahandler.thrift.attachments.AttachmentContent;
import org.eclipse.sw360.datahandler.thrift.attachments.AttachmentService;
import org.eclipse.sw360.datahandler.thrift.users.User;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

public class AttachmentFrontendUtils {

private static final Logger log = Logger.getLogger(AttachmentFrontendUtils.class);
protected final AttachmentService.Iface client;

private AttachmentStreamConnector connector;
// TODO add Config class and DI
private final Duration downloadTimeout = Duration.durationOf(30, TimeUnit.SECONDS);

public AttachmentFrontendUtils() {
this(new ThriftClients());
}

public AttachmentFrontendUtils(ThriftClients thriftClients) {
client = thriftClients.makeAttachmentClient();
}

public InputStream getStreamToServeAFile(Collection<AttachmentContent> attachments, User user, Object context)
throws TException, IOException {
if(attachments == null || attachments.size() == 0){
throw new SW360Exception("Tried to download empty set of Attachments");
}else if(attachments.size() == 1){
return getConnector().getAttachmentStream(attachments.stream().findAny().get(), user, context);
} else {
return getConnector().getAttachmentBundleStream(new HashSet<>(attachments), user, context);
}
}

private synchronized void makeConnector() throws TException {
if (connector == null) {
try {
connector = new AttachmentStreamConnector(downloadTimeout);
} catch (MalformedURLException e) {
log.error("Invalid database address received...", e);
throw new TException(e);
}
}
}

public AttachmentStreamConnector getConnector() throws TException {
if (connector == null) makeConnector();
return connector;
}

public AttachmentContent getAttachmentContent(String id) throws TException {
return client.getAttachmentContent(id);
}

public AttachmentContent makeAttachmentContent(AttachmentContent attachmentContent) throws TException {
return client.makeAttachmentContent(attachmentContent);
}

public Attachment getAttachmentForDisplay(User user, String attachmentContentId) {
try {
String filename = getAttachmentContent(attachmentContentId).getFilename();
return CommonUtils.getNewAttachment(user, attachmentContentId, filename);
} catch (TException e) {
log.error("Could not get attachment content", e);
}
return null;
}

public void deleteAttachments(Set<String> attachmentContentIds){
try {
for(String id: attachmentContentIds) {
client.deleteAttachmentContent(id);
}
} catch (TException e){
log.error("Could not delete attachments from database.",e);
}
}


public Attachment uploadAttachmentContent(AttachmentContent attachmentContent, InputStream fileStream, User sw360User)
throws TException {
final AttachmentStreamConnector attachmentStreamConnector = getConnector();
if (attachmentContent != null) {
try {
attachmentStreamConnector.uploadAttachment(attachmentContent, fileStream);
return CommonUtils.getNewAttachment(sw360User, attachmentContent.getId(), attachmentContent.getFilename());
} catch (TException e) {
log.error("Error saving attachment part", e);
}
}
return null;
}

protected AttachmentContent updateAttachmentContent(AttachmentContent attachment) throws TException {
try {
client.updateAttachmentContent(attachment);
} catch (SW360Exception e) {
log.error("Error updating attachment", e);
return null;
}
return attachment;
}
}
5 changes: 5 additions & 0 deletions rest/resource-server/pom.xml
Expand Up @@ -179,6 +179,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.sw360</groupId>
<artifactId>commonIO</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
Expand Down

0 comments on commit 62f0299

Please sign in to comment.