Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
minerva
core
Commits
af3e1ce3
Commit
af3e1ce3
authored
Oct 24, 2019
by
Piotr Gawron
Browse files
big models are returned as zip files
parent
3d5b4c0a
Pipeline
#15476
failed with stage
in 14 minutes and 36 seconds
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
CHANGELOG
View file @
af3e1ce3
minerva
(
15.0.0
~
alpha
.0
)
stable
;
urgency
=
medium
*
Small
improvement
:
when
downloading
a
map
results
in
too
big
file
(>
1
MB
)
the
content
is
compressed
and
returned
as
a
zip
file
(#
348
)
*
Bug
fix
:
position
of
structural
state
is
preserved
on
upload
CellDesigner
file
(#
671
)
...
...
rest-api/src/main/java/lcsb/mapviewer/api/BaseController.java
View file @
af3e1ce3
package
lcsb.mapviewer.api
;
import
java.io.IOException
;
import
java.io.UnsupportedEncodingException
;
import
java.io.*
;
import
java.net.URLDecoder
;
import
java.util.*
;
import
java.util.zip.ZipEntry
;
import
java.util.zip.ZipOutputStream
;
import
org.apache.logging.log4j.LogManager
;
import
org.apache.logging.log4j.Logger
;
...
...
@@ -21,7 +22,9 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
import
com.google.gson.Gson
;
import
lcsb.mapviewer.common.Configuration
;
import
lcsb.mapviewer.common.MimeType
;
import
lcsb.mapviewer.common.exception.InvalidStateException
;
import
lcsb.mapviewer.model.cache.FileEntry
;
public
abstract
class
BaseController
{
private
Logger
logger
=
LogManager
.
getLogger
(
BaseController
.
class
);
...
...
@@ -114,4 +117,22 @@ public abstract class BaseController {
return
result
;
}
protected
ResponseEntity
<
byte
[]>
sendAsZip
(
FileEntry
originalFile
)
throws
IOException
{
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream
();
ZipOutputStream
zos
=
new
ZipOutputStream
(
baos
);
ZipEntry
entry
=
new
ZipEntry
(
originalFile
.
getOriginalFileName
());
zos
.
putNextEntry
(
entry
);
zos
.
write
(
originalFile
.
getFileContent
());
zos
.
closeEntry
();
zos
.
close
();
return
ResponseEntity
.
ok
().
contentLength
(
baos
.
size
())
.
contentType
(
MediaType
.
parseMediaType
(
MimeType
.
ZIP
.
getTextRepresentation
()))
.
header
(
"Content-Disposition"
,
"attachment; filename="
+
originalFile
.
getOriginalFileName
()
+
".zip"
)
.
body
(
baos
.
toByteArray
());
}
}
rest-api/src/main/java/lcsb/mapviewer/api/projects/models/ModelController.java
View file @
af3e1ce3
package
lcsb.mapviewer.api.projects.models
;
import
java.io.IOException
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.*
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.logging.log4j.LogManager
;
import
org.apache.logging.log4j.Logger
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.http.MediaType
;
import
org.springframework.http.ResponseEntity
;
...
...
@@ -12,12 +12,12 @@ import org.springframework.security.access.prepost.PreAuthorize;
import
org.springframework.security.core.Authentication
;
import
org.springframework.web.bind.annotation.*
;
import
lcsb.mapviewer.api.*
;
import
lcsb.mapviewer.api.BaseController
;
import
lcsb.mapviewer.api.QueryException
;
import
lcsb.mapviewer.commands.CommandExecutionException
;
import
lcsb.mapviewer.co
nverter.ConverterException
;
import
lcsb.mapviewer.co
mmon.MimeType
;
import
lcsb.mapviewer.converter.graphics.DrawingException
;
import
lcsb.mapviewer.model.cache.FileEntry
;
import
lcsb.mapviewer.model.map.InconsistentModelException
;
import
lcsb.mapviewer.model.map.layout.InvalidColorSchemaException
;
import
lcsb.mapviewer.model.user.User
;
import
lcsb.mapviewer.services.interfaces.IUserService
;
...
...
@@ -26,6 +26,8 @@ import lcsb.mapviewer.services.interfaces.IUserService;
@RequestMapping
(
value
=
"/projects/{projectId:.+}/models"
,
produces
=
MediaType
.
APPLICATION_JSON_VALUE
)
public
class
ModelController
extends
BaseController
{
Logger
logger
=
LogManager
.
getLogger
();
private
ModelRestImpl
modelController
;
private
IUserService
userService
;
...
...
@@ -87,7 +89,8 @@ public class ModelController extends BaseController {
}
@PreAuthorize
(
"hasAnyAuthority('IS_ADMIN', 'READ_PROJECT:' + #projectId)"
)
@RequestMapping
(
value
=
"/{modelId:.+}:downloadModel"
,
method
=
{
RequestMethod
.
GET
,
RequestMethod
.
POST
})
@RequestMapping
(
value
=
"/{modelId:.+}:downloadModel"
,
method
=
{
RequestMethod
.
GET
,
RequestMethod
.
POST
},
produces
=
{
MediaType
.
APPLICATION_OCTET_STREAM_VALUE
,
"application/zip"
})
public
ResponseEntity
<
byte
[]>
getModelAsModelFile
(
Authentication
authentication
,
@PathVariable
(
value
=
"projectId"
)
String
projectId
,
...
...
@@ -97,16 +100,33 @@ public class ModelController extends BaseController {
@RequestParam
(
value
=
"backgroundOverlayId"
,
defaultValue
=
""
)
String
backgroundOverlayId
,
@RequestParam
(
value
=
"polygonString"
,
defaultValue
=
""
)
String
polygonString
,
@RequestParam
(
value
=
"elementIds"
,
defaultValue
=
""
)
String
elementIds
,
@RequestParam
(
value
=
"reactionIds"
,
defaultValue
=
""
)
String
reactionIds
)
throws
QueryException
,
IOException
,
InvalidColorSchemaException
,
CommandExecutionException
,
ConverterException
,
InconsistentModelException
{
@RequestParam
(
value
=
"reactionIds"
,
defaultValue
=
""
)
String
reactionIds
,
@RequestHeader
(
"Accept"
)
String
accept
)
throws
Exception
{
User
user
=
userService
.
getUserByLogin
(
authentication
.
getName
());
FileEntry
file
=
modelController
.
getModelAsModelFile
(
projectId
,
modelId
,
handlerClass
,
overlayIds
,
polygonString
,
elementIds
,
reactionIds
,
user
,
backgroundOverlayId
);
projectId
,
modelId
,
handlerClass
,
overlayIds
,
polygonString
,
elementIds
,
reactionIds
,
user
,
backgroundOverlayId
);
if
(
isMimeTypeIncluded
(
accept
,
MimeType
.
ZIP
.
getTextRepresentation
()))
{
return
sendAsZip
(
file
);
}
if
(
file
.
getFileContent
().
length
>=
1024
*
1024
)
{
return
sendAsZip
(
file
);
}
return
ResponseEntity
.
ok
().
contentLength
(
file
.
getFileContent
().
length
)
.
contentType
(
MediaType
.
APPLICATION_OCTET_STREAM
)
.
header
(
"Content-Disposition"
,
"attachment; filename="
+
file
.
getOriginalFileName
())
.
body
(
file
.
getFileContent
());
}
private
boolean
isMimeTypeIncluded
(
String
accept
,
String
mimeType
)
{
List
<
MediaType
>
mediaTypes
=
MediaType
.
parseMediaTypes
(
accept
);
for
(
MediaType
mediaType
:
mediaTypes
)
{
if
(
Objects
.
equals
(
mediaType
.
getType
()
+
"/"
+
mediaType
.
getSubtype
(),
mimeType
))
{
return
true
;
}
}
return
false
;
}
}
\ No newline at end of file
web/src/test/java/lcsb/mapviewer/web/MapControllerIntegrationTest.java
View file @
af3e1ce3
...
...
@@ -15,12 +15,14 @@ import org.springframework.http.MediaType;
import
org.springframework.mock.web.MockHttpSession
;
import
org.springframework.test.annotation.Rollback
;
import
org.springframework.test.context.junit4.SpringJUnit4ClassRunner
;
import
org.springframework.test.web.servlet.MvcResult
;
import
org.springframework.test.web.servlet.RequestBuilder
;
import
org.springframework.transaction.annotation.Transactional
;
import
com.google.gson.JsonParser
;
import
lcsb.mapviewer.common.Configuration
;
import
lcsb.mapviewer.common.MimeType
;
import
lcsb.mapviewer.converter.graphics.PngImageGenerator
;
import
lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser
;
import
lcsb.mapviewer.model.Project
;
...
...
@@ -278,13 +280,29 @@ public class MapControllerIntegrationTest extends ControllerIntegrationTest {
RequestBuilder
request
=
get
(
"/projects/"
+
TEST_PROJECT
+
"/models/"
+
map
.
getId
()
+
":downloadModel?"
+
"handlerClass="
+
CellDesignerXmlParser
.
class
.
getCanonicalName
())
.
contentType
(
MediaType
.
APPLICATION_FORM_URLENCODED
)
.
session
(
session
);
mockMvc
.
perform
(
request
)
.
andExpect
(
status
().
is2xxSuccessful
());
}
@Test
public
void
testDownloadModelAsZip
()
throws
Exception
{
MockHttpSession
session
=
createSession
(
ControllerIntegrationTest
.
BUILT_IN_TEST_ADMIN_LOGIN
,
ControllerIntegrationTest
.
BUILT_IN_TEST_ADMIN_PASSWORD
);
RequestBuilder
request
=
get
(
"/projects/"
+
TEST_PROJECT
+
"/models/"
+
map
.
getId
()
+
":downloadModel?"
+
"handlerClass="
+
CellDesignerXmlParser
.
class
.
getCanonicalName
())
.
accept
(
MimeType
.
ZIP
.
getTextRepresentation
()+
";q=0.8"
)
.
session
(
session
);
MvcResult
result
=
mockMvc
.
perform
(
request
)
.
andExpect
(
status
().
is2xxSuccessful
())
.
andReturn
();
assertEquals
(
MimeType
.
ZIP
.
getTextRepresentation
(),
result
.
getResponse
().
getContentType
());
assertTrue
(
result
.
getResponse
().
getHeader
(
"Content-Disposition"
).
endsWith
(
".zip"
));
}
@Test
public
void
testDownloadModelWithUndefinedProject
()
throws
Exception
{
MockHttpSession
session
=
createSession
(
ControllerIntegrationTest
.
BUILT_IN_TEST_ADMIN_LOGIN
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment