public Response executeStreamGet()

in stack/rest/src/main/java/org/apache/usergrid/rest/applications/ServiceResource.java [847:964]


    public Response executeStreamGet( @Context UriInfo ui, @PathParam("entityId") PathSegment entityId,
                                      @HeaderParam("range") String rangeHeader,
                                      @HeaderParam("if-modified-since") String modifiedSince ) throws Exception {

        if(logger.isTraceEnabled()){
            logger.trace( "ServiceResource.executeStreamGet" );
        }

        // needed for testing
        this.binaryStore = binaryStoreFactory.getBinaryStore( properties.getProperty(PROPERTIES_USERGRID_BINARY_UPLOADER) );

        ApiResponse response = createApiResponse();
        response.setAction( "get" );
        response.setApplication( services.getApplication() );
        response.setParams( ui.getQueryParameters() );
        ServiceResults serviceResults = executeServiceRequest( ui, response, ServiceAction.GET, null );
        Entity entity = serviceResults.getEntity();

        if(logger.isTraceEnabled()){
            logger.trace( "In ServiceResource.executeStreamGet with id: {}, range: {}, modifiedSince: {}",
                entityId, rangeHeader, modifiedSince );
        }

        Map<String, Object> fileMetadata = AssetUtils.getFileMetadata( entity );

        // return a 302 if not modified
        Date modified = AssetUtils.fromIfModifiedSince( modifiedSince );
        if ( modified != null ) {
            Long lastModified = ( Long ) fileMetadata.get( AssetUtils.LAST_MODIFIED );
            if ( lastModified - modified.getTime() < 0 ) {
                return Response.status( Response.Status.NOT_MODIFIED ).build();
            }
        }

        boolean range = StringUtils.isNotBlank( rangeHeader );
        long start = 0, end = 0, contentLength = 0;
        InputStream inputStream;

        if ( range ) { // honor range request, calculate start & end

            String rangeValue = rangeHeader.trim().substring( "bytes=".length() );
            contentLength = ( Long ) fileMetadata.get( AssetUtils.CONTENT_LENGTH );
            end = contentLength - 1;
            if ( rangeValue.startsWith( "-" ) ) {
                start = contentLength - 1 - Long.parseLong( rangeValue.substring( "-".length() ) );
            }
            else {
                String[] startEnd = rangeValue.split( "-" );
                long parsedStart = Long.parseLong( startEnd[0] );
                if ( parsedStart > start && parsedStart < end ) {
                    start = parsedStart;
                }
                if ( startEnd.length > 1 ) {
                    long parsedEnd = Long.parseLong( startEnd[1] );
                    if ( parsedEnd > start && parsedEnd < end ) {
                        end = parsedEnd;
                    }
                }
            }
            try {
                inputStream = binaryStore.read( getApplicationId(), entity, start, end - start );
            }catch(AwsPropertiesNotFoundException apnfe){
                logger.error( "Amazon Property needed for this operation not found",apnfe );
                return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
            }catch(RuntimeException re){
                logger.error(re.getMessage());
                return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
            }
        }
        else { // no range
            try {
                inputStream = binaryStore.read( getApplicationId(), entity );
            }catch(AwsPropertiesNotFoundException apnfe){
                logger.error( "Amazon Property needed for this operation not found",apnfe );
                return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
            }
            catch(AmazonServiceException ase){
                if( ase.getStatusCode() > 499 ){
                    logger.error(ase.getMessage());
                }else if(logger.isDebugEnabled()){
                    logger.debug(ase.getMessage());
                }
                return Response.status(ase.getStatusCode()).build();
            }
            catch (StorageException se){
                if( se.getCode() > 499 ){
                    logger.error(se.getMessage());
                }else if(logger.isDebugEnabled()){
                    logger.debug(se.getMessage());
                }
                return Response.status(se.getCode()).build();
            }
            catch(RuntimeException re){
                logger.error(re.getMessage());
                return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
            }
        }

        // return 404 if not found
        if ( inputStream == null ) {
            return Response.status( Response.Status.NOT_FOUND ).build();
        }

        Long lastModified = ( Long ) fileMetadata.get( AssetUtils.LAST_MODIFIED );
        Response.ResponseBuilder responseBuilder =
                Response.ok( inputStream ).type( ( String ) fileMetadata.get( AssetUtils.CONTENT_TYPE ) )
                        .lastModified( new Date( lastModified ) );

        if ( fileMetadata.get( AssetUtils.E_TAG ) != null ) {
            responseBuilder.tag( ( String ) fileMetadata.get( AssetUtils.E_TAG ) );
        }

        if ( range ) {
            responseBuilder.header( "Content-Range", "bytes " + start + "-" + end + "/" + contentLength );
        }

        return responseBuilder.build();
    }