Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Story/vspc 204 #308

Open
wants to merge 129 commits into
base: develop
Choose a base branch
from
Open

Story/vspc 204 #308

wants to merge 129 commits into from

Conversation

pkharge
Copy link
Contributor

@pkharge pkharge commented Jul 29, 2022

Guidelines for Pull Requests

If you haven't yet read our code review guidelines, please do so, You can find them here.

Please confirm the following by adding an x for each item (turn [ ] into [x]).

  • I have removed all code style changes that are not necessary (e.g. changing blanks across the whole file that don’t need to be changed, adding empty lines in parts other than your own code)
  • I am not making any changes to files that don’t have any effect (e.g. imports added that don’t need to be added)
  • I do not have any sysout statements in my code or commented out code that isn’t needed anymore
  • I am not reformatting any files in the wrong format or without cause.
  • I am not changing file encoding or line endings to something else than UTF-8, LF
  • My pull request does not show an insane amount of files being changed although my ticket only requires a few files being changed
  • I have added Javadoc/documentation where appropriate
  • I have added test cases where appropriate
  • I have explained any part of my code/implementation decisions that is not be self-explanatory

Please provide a brief description of your ticket

The user would get a zip file that contains one html page for each page + any css, javascript, etc.

Anything else the reviewer needs to know?

... describe here ...

@diging-jenkins
Copy link

Can one of the admins verify this patch?

@pkharge pkharge marked this pull request as draft July 29, 2022 23:40
@pkharge pkharge marked this pull request as ready for review August 1, 2022 23:16
Copy link
Member

@jdamerow jdamerow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't not go through everything but given I'm asking for some major changes, I'll leave it with this for now.

});
IOUtils.close(responseZipStream);
IOUtils.close(bufferedOutputStream);
IOUtils.close(byteArrayOutputStream);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can probably be tightened up by using try-with statements

responseZipStream.closeEntry();

} catch (IOException e) {
System.err.println(e);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

return byteArrayOutputStream.toByteArray();

} catch (IOException e) {
throw new IOException(e);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is no point in wrapping an IOException in another IOException

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this still



@Service
public class DownloadsManager {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs an interface

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I can tell so far, this class needs to be a little refactored. There should be several methods:

  • create a snapshot (or whatever you want to call the generated html pages)
  • get one
  • list all
  • get generated files

When the user generates a new snapshot the create method is called. This should be an @Async method as it might take a while. The user sees a progress page (polling for updates from the front end, not just one call as the server might time out).
When the generation process is done, the user will be sent to the page for that snapshot. The create method should return the created ExhibitionDownload object. The get method is probably called here, to get the object by its id. If the user wants to download the files, they can do so from that page (get generated files method will be called).
The list all snapshots page will call the list method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jdamerow , want to check my understanding on this once.
The first time user clicks on download button, the async rest api will return an newly created exhibitionDownload object with a unique folder name (used timestamps). this api will trigger create snapshot method.
then Ui will poll another rest api (this will be an simple GET api) by sending exhibitionDownload object as input, untill the requested folder is ready. once its ready, the folder should be download as zip folder.

so there will be 2 different rest apis in backend, one async which just returns exhibitionDownload object and trigger createSnapshot method. another one will be used simply to poll.

is this understanding correct?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not 100% sure. What do you mean by "async rest api"?

The flow would be:

  • POST request to start zip generation (the request itself does not have to be async, but it will start an async method on the server)
  • the controller will return an id that the client can then use to poll (id could be the id of an exhibitionDownload object if that is being created and returned by the async method)
  • "then Ui will poll another rest api (this will be an simple GET api)" - yes, "by sending exhibitionDownload object as input" -> not sure what that means. It would use the id returned in the previous step
  • "untill the requested folder is ready." - yes
  • "once its ready, the folder should be download as zip folder." - once it's ready the user should be able to down load, it should probably show a message that the generation is done or something. It does not have to automatically start downloading.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jdamerow , to show the progress of download to the user, do we want to create a separate page where user will be redirected to, or can we show it within a section in the same downloadlist page?
I tried putting it in an alert box, but if the page gets refreshed, the user won't be able to see the notification.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

either is fine.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if it's on the same page and the user won't see the progress anymore after reloading the page, there is needs to be another indication that makes clear that export is in progress.

});
IOUtils.close(responseZipStream);
IOUtils.close(bufferedOutputStream);
IOUtils.close(byteArrayOutputStream);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are these needed since you're using the try-with statement?

Resource resource = null;
try {
String pathToResources = request.getServletContext().getRealPath("") + "/resources";
String exhibitionFolderName= "Exhibition"+ LocalDateTime.now();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

business logic that should not be in the controller

@jdamerow jdamerow closed this Oct 24, 2022
@pooja-thalur pooja-thalur reopened this Jun 18, 2024
* @param sequenceHistory the sequence history object having the history of sequences
* @throws FileStorageException
*/
public void downloadSpace(Space space, String exhibitionFolderName, SequenceHistory sequenceHistory) throws FileStorageException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this method is not downloading anything, is it? Just creating a snapshot/rendering the pages?

* @param spaceFolderPath he path of the folder where the module's content will be stored
*
*/
private void downloadModule(IModule module, ISpace space, String imagesFolderPath, String spaceFolderPath) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

* @throws FileStorageException
*
*/
private void downloadSequences(ISequence startSequence, IModule module, ISpace space, String spaceFolderPath,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and here

if(slide instanceof BranchingPoint) {
BranchingPoint branchingPoint = (BranchingPoint) slide;
List<IChoice> choices = branchingPoint.getChoices();
choices.forEach(choice -> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these three lines could be merged into one, or at least 2.

public SnapshotTask getSnapshotTask(String id) throws ExhibitionSnapshotNotFoundException{
Optional<SnapshotTask> snapshotTask = snapshotTaskRepository.findById(id);
if(snapshotTask.isPresent()) {
logger.debug("hereee");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

}

@RequestMapping(value = "/staff/exhibit/download/{id}", method = RequestMethod.GET)
public ResponseEntity<Resource> downloadExhibitionFolder(@PathVariable("id") String id, @RequestParam("folderName") String exhibitionSnapshotFolderName , HttpServletRequest request)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be in its own controller

}

@RequestMapping(value = "/staff/exhibit/snapshot", method = RequestMethod.POST)
public ResponseEntity<ExhibitionSnapshot> createExhibitionSnapshot(HttpServletRequest request, HttpServletResponse response, Model model) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be in its own controller



@RequestMapping(value = "/staff/exhibit/download/checkStatus/{id}", method = RequestMethod.GET)
public ResponseEntity<Boolean> exhibitionDownloadStatus(@PathVariable("id") String id, @RequestParam("folderName") String exhibitionDownloadFolderName , HttpServletRequest request) throws ExhibitionSnapshotNotFoundException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should probably be in the controller with createExhibitionSnapshot

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait, what's the difference between this endpoint and getLatestSnapshotStatus? Would one method returning the status of a task not be enough?

public class SnapshotTaskController {

@Autowired
ISnapshotManager snapshotManager;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs to be private

@jdamerow jdamerow closed this Jun 19, 2024
@pooja-thalur pooja-thalur reopened this Jul 26, 2024
* @throws IOException
*/
@Override
public byte[] getZip(String zipFilename) throws ExhibitionSnapshotNotFoundException, IOException, FileNotFoundException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, is this needed? Why can't it use the getFile method?

public byte[] getZip(String zipFilename) throws ExhibitionSnapshotNotFoundException, IOException, FileNotFoundException {
File file = new File(path + File.separator + zipFilename + ".zip");
if(!file.exists()){
throw new ExhibitionSnapshotNotFoundException(zipFilename);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the storage engine shouldn't know anything about what a file is for, so it should not through a snapshot exception. If this method is needed (and getFile can't be used), then it should be a generic method that could be use for any file (e.g. make it getFileBytes or something).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But also, there is getMediaContent, which also seems to do more or less the same thing

createSlideSnapshot(slide, sequence, module, space, spaceFolderName, imagesFolderName);
if(slide instanceof BranchingPoint) {
((BranchingPoint) slide).getChoices().forEach(choice -> {
if(!choice.getSequence().getId().equals(sequence.getId())) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there needs to be a "bigger" check. The linked sequence could have a branching point that links back to the first sequence, that would still create an infinite loop here, wouldn't it?

context.setVariable("startSequenceId", startSequenceId);
ISequence sequenceExist=moduleManager.checkIfSequenceExists(moduleId, sequenceId);
if (sequenceExist==null) {
throw new SequenceNotFoundException(sequenceId);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah alright, no that's fine.

ExhibitionSnapshot exhibitionSnapshot = new ExhibitionSnapshot();
createSnapshotFolder(exhibitionSnapshot, exhibitionFolderName);
SnapshotTask snapshotTask = createSnapshotTask(exhibitionSnapshot);
exhibitionSnapshot.setSnapshotTask(snapshotTask);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this method should set the task complete after the zip has been generated.


if(exhibitionSnapshot.isPresent()) {
try {
return storageEngineDownloads.getZip(exhibitionSnapshot.get().getFolderName());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if the snapshot generation is not done yet? there shouldn't be a not found exception in that case.

@Autowired
private ISnapshotManager snapshotManager;

@RequestMapping("/staff/downloads/list")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/staff/snapshot/list


private final Logger logger = LoggerFactory.getLogger(getClass());

@RequestMapping(value = "/staff/exhibit/snapshot", method = RequestMethod.POST)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/staff/snapshot/create

}
}

@RequestMapping(value = "/staff/exhibit/download/{id}", method = RequestMethod.GET)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/staff/snapshot/{id}


private final Logger logger = LoggerFactory.getLogger(getClass());

@RequestMapping(value = "/staff/exhibit/snapshot/status", method = RequestMethod.GET)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/staff/snapshot/{id}/status

@jdamerow jdamerow closed this Aug 30, 2024
@pooja-thalur pooja-thalur reopened this Nov 6, 2024
@pooja-thalur pooja-thalur reopened this Nov 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants