dhis2-devs team mailing list archive
-
dhis2-devs team
-
Mailing list archive
-
Message #41365
[Branch ~dhis2-devs-core/dhis2/trunk] Rev 21068: EventController getting ready for event data value file types
------------------------------------------------------------
revno: 21068
committer: Abyot Asalefew Gizaw <abyota@xxxxxxxxx>
branch nick: dhis2
timestamp: Mon 2015-11-16 16:47:16 +0100
message:
EventController getting ready for event data value file types
modified:
dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EventController.java
--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk
Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EventController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EventController.java 2015-11-02 03:24:16 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EventController.java 2015-11-16 15:47:16 +0000
@@ -28,6 +28,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+import org.apache.commons.io.IOUtils;
import org.hisp.dhis.common.OrganisationUnitSelectionMode;
import org.hisp.dhis.commons.util.StreamUtils;
import org.hisp.dhis.dataelement.DataElement;
@@ -35,6 +36,7 @@
import org.hisp.dhis.dataelement.DataElementService;
import org.hisp.dhis.dxf2.common.IdSchemes;
import org.hisp.dhis.dxf2.common.ImportOptions;
+import org.hisp.dhis.dxf2.events.event.DataValue;
import org.hisp.dhis.dxf2.events.event.Event;
import org.hisp.dhis.dxf2.events.event.EventSearchParams;
import org.hisp.dhis.dxf2.events.event.EventService;
@@ -49,7 +51,9 @@
import org.hisp.dhis.dxf2.importsummary.ImportSummary;
import org.hisp.dhis.dxf2.render.RenderService;
import org.hisp.dhis.dxf2.utils.InputUtils;
+import org.hisp.dhis.dxf2.webmessage.WebMessage;
import org.hisp.dhis.dxf2.webmessage.WebMessageException;
+import org.hisp.dhis.dxf2.webmessage.responses.FileResourceWebMessageResponse;
import org.hisp.dhis.event.EventStatus;
import org.hisp.dhis.importexport.ImportStrategy;
import org.hisp.dhis.program.Program;
@@ -58,12 +62,14 @@
import org.hisp.dhis.scheduling.TaskCategory;
import org.hisp.dhis.scheduling.TaskId;
import org.hisp.dhis.system.scheduling.Scheduler;
+import org.hisp.dhis.trackedentitydatavalue.TrackedEntityDataValue;
import org.hisp.dhis.user.CurrentUserService;
import org.hisp.dhis.webapi.service.WebMessageService;
import org.hisp.dhis.webapi.utils.ContextUtils;
import org.hisp.dhis.webapi.utils.WebMessageUtils;
import org.hisp.dhis.webapi.webdomain.WebOptions;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
@@ -72,12 +78,20 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
+import org.hisp.dhis.fileresource.FileResource;
+import org.hisp.dhis.fileresource.FileResourceDomain;
+import org.hisp.dhis.fileresource.FileResourceService;
+import org.hisp.dhis.fileresource.FileResourceStorageStatus;
+
+import com.google.common.io.ByteSource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.net.URI;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@@ -129,6 +143,9 @@
@Autowired
private ProgramStageInstanceService programStageInstanceService;
+
+ @Autowired
+ private FileResourceService fileResourceService;
// -------------------------------------------------------------------------
// READ
@@ -332,6 +349,124 @@
return metaData;
}
+ @RequestMapping( value = "/files", method = RequestMethod.GET)
+ @PreAuthorize( "hasRole('ALL') or hasRole('F_TRACKED_ENTITY_DATAVALUE_ADD')" )
+ public void getEventDataValueFile( @RequestParam String eventUid, @RequestParam String dataElementUid, HttpServletResponse response, HttpServletRequest request ) throws Exception
+ {
+ Event event = eventService.getEvent( eventUid );
+
+ if ( event == null )
+ {
+ throw new WebMessageException( WebMessageUtils.notFound( "Event not found for ID " + eventUid ) );
+ }
+
+ DataElement dataElement = dataElementService.getDataElement( dataElementUid );
+
+ if ( dataElement == null )
+ {
+ throw new WebMessageException( WebMessageUtils.notFound( "DataElement not found for ID " + dataElementUid ) );
+ }
+
+ if ( !dataElement.isFileType() )
+ {
+ throw new WebMessageException( WebMessageUtils.conflict( "DataElement must be of type file" ) );
+ }
+
+ // ---------------------------------------------------------------------
+ // Get file resource
+ // ---------------------------------------------------------------------
+
+ String uid = null;
+
+ for ( DataValue value : event.getDataValues() )
+ {
+ if ( value.getDataElement() == dataElement.getUid() )
+ {
+ uid = value.getValue();
+ break;
+ }
+ }
+
+ if( uid == null)
+ {
+ throw new WebMessageException( WebMessageUtils.conflict( "DataElement must be of type file" ) );
+ }
+
+
+ FileResource fileResource = fileResourceService.getFileResource( uid );
+
+ if ( fileResource == null || fileResource.getDomain() != FileResourceDomain.DATA_VALUE )
+ {
+ throw new WebMessageException( WebMessageUtils.notFound( "A data value file resource with id " + uid + " does not exist." ) );
+ }
+
+ if ( fileResource.getStorageStatus() != FileResourceStorageStatus.STORED )
+ {
+ // Special case:
+ // The FileResource exists and has been tied to this DataValue, however, the underlying file
+ // content is still not stored to the (most likely external) file store provider.
+
+ // HTTP 409, for lack of a more suitable status code
+ WebMessage webMessage = WebMessageUtils.conflict( "The content is being processed and is not available yet. Try again later.",
+ "The content requested is in transit to the file store and will be available at a later time." );
+ webMessage.setResponse( new FileResourceWebMessageResponse( fileResource ) );
+
+ throw new WebMessageException( webMessage );
+ }
+
+ ByteSource content = fileResourceService.getFileResourceContent( fileResource );
+
+ if ( content == null )
+ {
+ throw new WebMessageException( WebMessageUtils.notFound( "The referenced file could not be found" ) );
+ }
+
+ // ---------------------------------------------------------------------
+ // Attempt to build signed URL request for content and redirect
+ // ---------------------------------------------------------------------
+
+ URI signedGetUri = fileResourceService.getSignedGetFileResourceContentUri( uid );
+
+ if ( signedGetUri != null )
+ {
+ response.setStatus( HttpServletResponse.SC_TEMPORARY_REDIRECT );
+ response.setHeader( HttpHeaders.LOCATION, signedGetUri.toASCIIString() );
+
+ return;
+ }
+
+ // ---------------------------------------------------------------------
+ // Build response and return
+ // ---------------------------------------------------------------------
+
+ response.setContentType( fileResource.getContentType() );
+ response.setContentLength( Math.round( fileResource.getContentLength() ) );
+ response.setHeader( HttpHeaders.CONTENT_DISPOSITION, "filename=" + fileResource.getName() );
+
+ // ---------------------------------------------------------------------
+ // Request signing is not available, stream content back to client
+ // ---------------------------------------------------------------------
+
+ InputStream inputStream = null;
+
+ try
+ {
+ inputStream = content.openStream();
+ IOUtils.copy( inputStream, response.getOutputStream() );
+ }
+ catch ( IOException e )
+ {
+ throw new WebMessageException( WebMessageUtils.error( "Failed fetching the file from storage",
+ "There was an exception when trying to fetch the file from the storage backend. " +
+ "Depending on the provider the root cause could be network or file system related." ) );
+ }
+ finally
+ {
+ IOUtils.closeQuietly( inputStream );
+ }
+
+ }
+
// -------------------------------------------------------------------------
// CREATE
// -------------------------------------------------------------------------