Loading vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/controller/UploadController.java +14 −5 Original line number Diff line number Diff line Loading @@ -99,13 +99,22 @@ public class UploadController extends BaseController { try { String uploadUrl = obtainUploadUrl(nodeUri); result.setUrl(uploadUrl); } catch (VOSpaceException ex) { result.setError(ex.getMessage()); } catch (Throwable t) { if (t instanceof VOSpaceException) { result.setError(t.getMessage()); } else { LOG.error("Error while obtaining upload URL for " + nodeUri, t); result.setError("Unable to obtain upload URL"); } try { // attempt to cleanup node metadata client.deleteNode(path); } catch (Throwable dt) { LOG.error("Unable to remove node after failed upload URL retrieval", dt); result.setError("Retrieval of upload URL failed. Manual cleanup of node metadata may be necessary"); } } return result; }, Runnable::run); // Passing current thread Executor to CompletableFuture to avoid "No thread-bound request found" exception } Loading vospace-ui-backend/src/test/java/it/inaf/ia2/vospace/ui/controller/UploadControllerTest.java +29 −0 Original line number Diff line number Diff line Loading @@ -16,8 +16,11 @@ import static org.hamcrest.core.IsNull.nullValue; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import org.mockito.Mock; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; Loading Loading @@ -158,6 +161,8 @@ public class UploadControllerTest { .andExpect(status().isOk()) .andExpect(jsonPath("$[0].error").value("Unable to connect")) .andExpect(jsonPath("$[0].url").value(nullValue())); verify(client, times(1)).deleteNode(eq("/mynode/test.txt")); } @Test Loading @@ -177,5 +182,29 @@ public class UploadControllerTest { .andExpect(status().isOk()) .andExpect(jsonPath("$[0].error").value("Unable to obtain upload URL")) .andExpect(jsonPath("$[0].url").value(nullValue())); verify(client, times(1)).deleteNode(eq("/mynode/test.txt")); } @Test public void testUploadUrlErrorWithNodeDeletionError() throws Exception { UploadFilesData data = new UploadFilesData(); data.setParentPath("/mynode"); data.setFiles(List.of("test.txt")); doThrow(new NullPointerException()).when(client).getFileServiceEndpoint(any()); doThrow(new VOSpaceException("error")).when(client).deleteNode(any()); mockMvc.perform(post("/preupload") .sessionAttr("user_data", user) .contentType(MediaType.APPLICATION_JSON) .content(MAPPER.writeValueAsString(data))) .andDo(print()) .andExpect(status().isOk()) .andExpect(jsonPath("$[0].error").value("Retrieval of upload URL failed. Manual cleanup of node metadata may be necessary")) .andExpect(jsonPath("$[0].url").value(nullValue())); verify(client, times(1)).deleteNode(eq("/mynode/test.txt")); } } Loading
vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/controller/UploadController.java +14 −5 Original line number Diff line number Diff line Loading @@ -99,13 +99,22 @@ public class UploadController extends BaseController { try { String uploadUrl = obtainUploadUrl(nodeUri); result.setUrl(uploadUrl); } catch (VOSpaceException ex) { result.setError(ex.getMessage()); } catch (Throwable t) { if (t instanceof VOSpaceException) { result.setError(t.getMessage()); } else { LOG.error("Error while obtaining upload URL for " + nodeUri, t); result.setError("Unable to obtain upload URL"); } try { // attempt to cleanup node metadata client.deleteNode(path); } catch (Throwable dt) { LOG.error("Unable to remove node after failed upload URL retrieval", dt); result.setError("Retrieval of upload URL failed. Manual cleanup of node metadata may be necessary"); } } return result; }, Runnable::run); // Passing current thread Executor to CompletableFuture to avoid "No thread-bound request found" exception } Loading
vospace-ui-backend/src/test/java/it/inaf/ia2/vospace/ui/controller/UploadControllerTest.java +29 −0 Original line number Diff line number Diff line Loading @@ -16,8 +16,11 @@ import static org.hamcrest.core.IsNull.nullValue; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import org.mockito.Mock; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; Loading Loading @@ -158,6 +161,8 @@ public class UploadControllerTest { .andExpect(status().isOk()) .andExpect(jsonPath("$[0].error").value("Unable to connect")) .andExpect(jsonPath("$[0].url").value(nullValue())); verify(client, times(1)).deleteNode(eq("/mynode/test.txt")); } @Test Loading @@ -177,5 +182,29 @@ public class UploadControllerTest { .andExpect(status().isOk()) .andExpect(jsonPath("$[0].error").value("Unable to obtain upload URL")) .andExpect(jsonPath("$[0].url").value(nullValue())); verify(client, times(1)).deleteNode(eq("/mynode/test.txt")); } @Test public void testUploadUrlErrorWithNodeDeletionError() throws Exception { UploadFilesData data = new UploadFilesData(); data.setParentPath("/mynode"); data.setFiles(List.of("test.txt")); doThrow(new NullPointerException()).when(client).getFileServiceEndpoint(any()); doThrow(new VOSpaceException("error")).when(client).deleteNode(any()); mockMvc.perform(post("/preupload") .sessionAttr("user_data", user) .contentType(MediaType.APPLICATION_JSON) .content(MAPPER.writeValueAsString(data))) .andDo(print()) .andExpect(status().isOk()) .andExpect(jsonPath("$[0].error").value("Retrieval of upload URL failed. Manual cleanup of node metadata may be necessary")) .andExpect(jsonPath("$[0].url").value(nullValue())); verify(client, times(1)).deleteNode(eq("/mynode/test.txt")); } }