getPipelineSuppliers() {
return JsonCustomObjectMatcher.formatSuppliers(
Arrays.asList("identifier", "name", "version", "description", "canExecute", "parameters"),
diff --git a/vip-api/src/test/java/fr/insalyon/creatis/vip/api/data/UserTestUtils.java b/vip-api/src/test/java/fr/insalyon/creatis/vip/api/data/UserTestUtils.java
index a0fc593a0..656ad3c9f 100644
--- a/vip-api/src/test/java/fr/insalyon/creatis/vip/api/data/UserTestUtils.java
+++ b/vip-api/src/test/java/fr/insalyon/creatis/vip/api/data/UserTestUtils.java
@@ -35,9 +35,11 @@
import fr.insalyon.creatis.vip.api.security.apikey.SpringApiPrincipal;
import fr.insalyon.creatis.vip.core.client.bean.User;
import fr.insalyon.creatis.vip.core.client.view.user.UserLevel;
+import fr.insalyon.creatis.vip.core.client.view.util.CountryCode;
import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors;
import org.springframework.test.web.servlet.request.RequestPostProcessor;
+import java.util.ArrayList;
import java.util.Collections;
/**
@@ -47,6 +49,8 @@ public class UserTestUtils {
static public User baseUser1;
static public User baseUser2;
+ static public User baseUser3;
+ static public User baseUser4;
static public SignUpUserDTO restUser1;
@@ -65,9 +69,14 @@ static public void reset() {
baseUser2 = new User("base2", "User2", "baseuser2@test.tst", null,
UserLevel.Advanced, null);
baseUser2.setFolder("user2");
+ baseUser3 = new User("base3", "User3", "baseuser3@test.tst", null,
+ UserLevel.Beginner, null);
+ baseUser3.setFolder("user3");
+ baseUser4 = new User("base4", "User4", "baseuser4@test.tst", null,
+ UserLevel.Beginner, null);
+ baseUser4.setFolder("user4");
- restUser1 = new SignUpUserDTO("base3", "User3", "baseuser3@test.tst", "test", baseUser2Password,
- UserLevel.Advanced, null, "test comment", Collections.singletonList("test applications"));
+ restUser1 = new SignUpUserDTO("base3", "User3", "baseuser3@test.tst", "test", baseUser2Password, CountryCode.lc, "test comment", new ArrayList<>());
}
public static RequestPostProcessor baseUser1() {
@@ -77,4 +86,12 @@ public static RequestPostProcessor baseUser1() {
public static RequestPostProcessor baseUser2() {
return SecurityMockMvcRequestPostProcessors.user(new SpringApiPrincipal(baseUser2));
}
+
+ public static RequestPostProcessor baseUser3() {
+ return SecurityMockMvcRequestPostProcessors.user(new SpringApiPrincipal(baseUser3));
+ }
+
+ public static RequestPostProcessor baseUser4() {
+ return SecurityMockMvcRequestPostProcessors.user(new SpringApiPrincipal(baseUser4));
+ }
}
diff --git a/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/config/BaseWebSpringIT.java b/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/config/BaseWebSpringIT.java
index b343cf8a8..e6cd22664 100644
--- a/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/config/BaseWebSpringIT.java
+++ b/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/config/BaseWebSpringIT.java
@@ -31,9 +31,14 @@
*/
package fr.insalyon.creatis.vip.api.rest.config;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import fr.insalyon.creatis.grida.client.GRIDAClient;
+import fr.insalyon.creatis.grida.client.GRIDAClientException;
import fr.insalyon.creatis.vip.api.rest.mockconfig.DataConfigurator;
+import fr.insalyon.creatis.vip.application.client.bean.AppVersion;
+import fr.insalyon.creatis.vip.application.integrationtest.BaseApplicationSpringIT;
import fr.insalyon.creatis.vip.application.server.business.*;
-import fr.insalyon.creatis.vip.core.integrationtest.database.BaseSpringIT;
+import fr.insalyon.creatis.vip.core.integrationtest.ServerMockConfig;
import fr.insalyon.creatis.vip.core.server.business.BusinessException;
import fr.insalyon.creatis.vip.core.server.business.ConfigurationBusiness;
import fr.insalyon.creatis.vip.core.server.dao.UserDAO;
@@ -42,6 +47,7 @@
import fr.insalyon.creatis.vip.datamanager.server.business.TransferPoolBusiness;
import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.BeforeEach;
+import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
@@ -53,11 +59,9 @@
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
+import java.io.File;
import java.io.IOException;
-import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
-import java.util.Collections;
-import java.util.Map;
/**
* Created by abonnet on 7/28/16.
@@ -71,10 +75,9 @@
* * login via with httpbasic(user, password)
* * use {@link WithMockUser} annotation
*
- * The interaction with VIP outside vip-api are mocked (see {@link SpringTestConfig} )
*/
@WebAppConfiguration
-abstract public class BaseWebSpringIT extends BaseSpringIT {
+abstract public class BaseWebSpringIT extends BaseApplicationSpringIT {
@Autowired
protected WebApplicationContext wac;
@@ -86,52 +89,15 @@ abstract public class BaseWebSpringIT extends BaseSpringIT {
@Autowired
protected ConfigurationBusiness configurationBusiness;
@Autowired
- protected WorkflowBusiness workflowBusiness;
- @Autowired
- protected ApplicationBusiness applicationBusiness;
- @Autowired
- protected ClassBusiness classBusiness;
- @Autowired
protected TransferPoolBusiness transferPoolBusiness;
@Autowired
protected SimulationBusiness simulationBusiness;
@Autowired
- protected EngineBusiness engineBusiness;
- @Autowired
protected LFCBusiness lfcBusiness;
-
@Autowired
protected LFCPermissionBusiness lfcPermissionBusiness;
-
- /* hack from :
- * https://stackoverflow.com/a/7201825
- */
- public static void setEnv(Map newenv) throws Exception {
- try {
- Class> processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment");
- Field theEnvironmentField = processEnvironmentClass.getDeclaredField("theEnvironment");
- theEnvironmentField.setAccessible(true);
- Map env = (Map) theEnvironmentField.get(null);
- env.putAll(newenv);
- Field theCaseInsensitiveEnvironmentField = processEnvironmentClass.getDeclaredField("theCaseInsensitiveEnvironment");
- theCaseInsensitiveEnvironmentField.setAccessible(true);
- Map cienv = (Map) theCaseInsensitiveEnvironmentField.get(null);
- cienv.putAll(newenv);
- } catch (NoSuchFieldException e) {
- Class[] classes = Collections.class.getDeclaredClasses();
- Map env = System.getenv();
- for (Class cl : classes) {
- if ("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {
- Field field = cl.getDeclaredField("m");
- field.setAccessible(true);
- Object obj = field.get(env);
- Map map = (Map) obj;
- map.clear();
- map.putAll(newenv);
- }
- }
- }
- }
+ @Autowired
+ protected GRIDAClient gridaClient;
@BeforeEach
@Override
@@ -173,18 +139,6 @@ public ConfigurationBusiness getConfigurationBusiness() {
return configurationBusiness;
}
- public WorkflowBusiness getWorkflowBusiness() {
- return workflowBusiness;
- }
-
- public ApplicationBusiness getApplicationBusiness() {
- return applicationBusiness;
- }
-
- public ClassBusiness getClassBusiness() {
- return classBusiness;
- }
-
public TransferPoolBusiness getTransferPoolBusiness() {
return transferPoolBusiness;
}
@@ -201,15 +155,54 @@ public LFCPermissionBusiness lfcPermissionBusiness() {
return lfcPermissionBusiness;
}
- /*
- @BeforeAll
- public static void setupEnvVariables() throws Exception {
- String fakeHomePath = Paths.get(ClassLoader.getSystemResource("TestHome").toURI())
- .toAbsolutePath().toString();
- setEnv(Collections.singletonMap("HOME", fakeHomePath));
- }*/
-
protected void configureDataFS() throws BusinessException {
DataConfigurator.configureFS(this);
}
+
+ protected static String asJsonString(final Object obj) {
+ try {
+ return new ObjectMapper().writeValueAsString(obj);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ protected AppVersion configureGwendiaTestApp(String appName, String groupName, String className, String versionName) throws BusinessException, GRIDAClientException, IOException {
+ return configureTestApp(appName, groupName, className, versionName, true);
+ }
+
+ protected AppVersion configureBoutiquesTestApp(String appName, String groupName, String className, String versionName) throws BusinessException, GRIDAClientException, IOException {
+ return configureTestApp(appName, groupName, className, versionName, false);
+ }
+
+ protected File getGwendiaTestFile() throws IOException {
+ return getResourceFromClasspath("gwendia/basic-gwendia.gwendia").getFile();
+ }
+
+ protected File getBoutiquesTestFile() throws IOException {
+ return getResourceFromClasspath("boutiques/test-boutiques.json").getFile();
+ }
+
+ protected AppVersion configureTestApp(String appName, String groupName, String className, String versionName, boolean gwendia) throws BusinessException, GRIDAClientException, IOException {
+ AppVersion appVersion = configureAnApplication(appName, versionName, groupName, className);
+ configureVersion(appVersion,
+ gwendia ? "/vip/testGroup (group)/path/to/test.gwendia" : null,
+ gwendia ? null : "/vip/testGroup (group)/path/to/desc-boutiques.json");
+
+ Mockito.when(server.getDataManagerPath()).thenReturn("/test/folder");
+
+ // localDir is datamanagerpath + "downloads" + groupRoot + dir(path)
+ File gwendiaFile = getGwendiaTestFile();
+ File jsonFile = getBoutiquesTestFile();
+ if (gwendia) {
+ Mockito.when(gridaClient.getRemoteFile(
+ ServerMockConfig.TEST_GROUP_ROOT + "/testGroup/path/to/test.gwendia",
+ "/test/folder/downloads"+ ServerMockConfig.TEST_GROUP_ROOT +"/testGroup/path/to")).thenReturn(gwendiaFile.getAbsolutePath());
+ } else {
+ Mockito.when(gridaClient.getRemoteFile(
+ ServerMockConfig.TEST_GROUP_ROOT + "/testGroup/path/to/desc-boutiques.json",
+ "/test/folder/downloads"+ ServerMockConfig.TEST_GROUP_ROOT +"/testGroup/path/to")).thenReturn(jsonFile.getAbsolutePath());
+ }
+ return appVersion;
+ }
}
diff --git a/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/AuthenticationControllerIT.java b/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/AuthenticationControllerIT.java
index b90fd92ce..51a41970b 100644
--- a/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/AuthenticationControllerIT.java
+++ b/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/AuthenticationControllerIT.java
@@ -31,18 +31,13 @@
*/
package fr.insalyon.creatis.vip.api.rest.itest;
-import fr.insalyon.creatis.vip.api.data.UserTestUtils;
import fr.insalyon.creatis.vip.api.exception.ApiException.ApiError;
import fr.insalyon.creatis.vip.api.rest.config.BaseWebSpringIT;
-import fr.insalyon.creatis.vip.core.server.business.ConfigurationBusiness;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import static fr.insalyon.creatis.vip.api.data.AuthenticationInfoTestUtils.jsonCorrespondsToAuthenticationInfo;
import static fr.insalyon.creatis.vip.api.data.CarminAPITestConstants.TEST_APIKEY_HEADER;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@@ -50,20 +45,27 @@
/**
* Created by abonnet on 8/21/17.
*/
-@Disabled
public class AuthenticationControllerIT extends BaseWebSpringIT {
+ @Test
+ public void badPasswordAuthentication() throws Exception {
+ createUser(emailUser2);
+ mockMvc.perform(
+ post("/rest/authenticate")
+ .contentType("application/json")
+ .content(getResourceAsString("jsonObjects/user-credentials.json")))
+ .andDo(print())
+ .andExpect(status().isUnauthorized())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
+ .andExpect(jsonPath("$.errorCode")
+ .value(ApiError.BAD_CREDENTIALS.getCode()));;
+ }
+
@Test
public void okAuthentication() throws Exception {
- ConfigurationBusiness configBness = getConfigurationBusiness();
- String email = UserTestUtils.baseUser1.getEmail();
- String apikey="plopplop";
- when(configBness.signin(anyString(), anyString()))
- .thenThrow(new RuntimeException());
- doReturn(UserTestUtils.baseUser1)
- .when(configBness)
- .signin(eq(email),eq("coucou"));
- when(configBness.getUserApikey(eq(email))).thenReturn(apikey);
+ createUserWithPassword(emailUser2, "coucou");
+ String apikey = getConfigurationBusiness().generateNewUserApikey(emailUser2);
+
mockMvc.perform(
post("/rest/authenticate")
.contentType("application/json")
@@ -71,12 +73,10 @@ public void okAuthentication() throws Exception {
.andDo(print())
.andExpect(jsonPath(
"$",
- jsonCorrespondsToAuthenticationInfo(TEST_APIKEY_HEADER, apikey)
- ))
+ jsonCorrespondsToAuthenticationInfo(TEST_APIKEY_HEADER, apikey)))
.andExpect(status().isOk());
}
-
@Test
public void missingInfoAuthentication() throws Exception {
mockMvc.perform(
diff --git a/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/PlatformControllerIT.java b/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/PlatformControllerIT.java
index f1eb24d47..9fe3e7b23 100644
--- a/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/PlatformControllerIT.java
+++ b/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/PlatformControllerIT.java
@@ -58,7 +58,6 @@
*
* Test method on platform path
*/
-@Disabled
public class PlatformControllerIT extends BaseWebSpringIT {
@Test
@@ -99,9 +98,10 @@ public void testPlatformProperties() throws Exception {
.andExpect(jsonPath("$.APIErrorCodesAndMessages[*]",
hasItems(
jsonCorrespondsToErrorCodeAndMessage(ApiError.GENERIC_API_ERROR),
- jsonCorrespondsToErrorCodeAndMessage(ApiError.NOT_ALLOWED_TO_USE_APPLICATION),
+ jsonCorrespondsToErrorCodeAndMessage(ApiError.NOT_ALLOWED_TO_USE_PIPELINE),
jsonCorrespondsToErrorCodeAndMessage(ApplicationError.USER_MAX_EXECS),
- jsonCorrespondsToErrorCodeAndMessage(8002, "The error message for 'bad credentials' cannot be known in advance"))));
+ jsonCorrespondsToErrorCodeAndMessage(ApiError.BAD_CREDENTIALS),
+ jsonCorrespondsToErrorCodeAndMessage(ApiError.INSUFFICIENT_AUTH.getCode(), "The error message for 'insufficient auth' cannot be known in advance"))));
}
diff --git a/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/RegisterUserControllerIT.java b/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/RegisterUserControllerIT.java
new file mode 100644
index 000000000..d1b582fa7
--- /dev/null
+++ b/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/RegisterUserControllerIT.java
@@ -0,0 +1,86 @@
+package fr.insalyon.creatis.vip.api.rest.itest;
+
+import fr.insalyon.creatis.vip.api.data.UserTestUtils;
+import fr.insalyon.creatis.vip.api.exception.ApiException;
+import fr.insalyon.creatis.vip.api.rest.config.BaseWebSpringIT;
+import fr.insalyon.creatis.vip.application.client.bean.AppClass;
+import fr.insalyon.creatis.vip.application.client.bean.Application;
+import fr.insalyon.creatis.vip.core.client.bean.Group;
+import fr.insalyon.creatis.vip.core.client.bean.User;
+import fr.insalyon.creatis.vip.core.client.view.user.UserLevel;
+import fr.insalyon.creatis.vip.core.client.view.util.CountryCode;
+import org.hamcrest.Matchers;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.http.MediaType;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+class RegisterUserControllerIT extends BaseWebSpringIT {
+
+ @BeforeEach
+ public void reset() {
+ UserTestUtils.reset();
+ }
+
+ @Test
+ public void registerEndpointOk() throws Exception {
+ mockMvc.perform(
+ post("/rest/register").
+ content(asJsonString(UserTestUtils.restUser1))
+ .contentType(MediaType.APPLICATION_JSON)
+ .accept(MediaType.APPLICATION_JSON))
+ .andDo(print())
+ .andExpect(status().isCreated());
+ User u = getConfigurationBusiness().getUserWithGroups(UserTestUtils.restUser1.getEmail());
+ Assertions.assertEquals(CountryCode.lc, u.getCountryCode());
+ Assertions.assertEquals(UserLevel.Beginner, u.getLevel());
+ Assertions.assertTrue(u.getGroups().isEmpty());
+ Assertions.assertFalse(u.isConfirmed());
+ Assertions.assertFalse(u.isAccountLocked());
+ Assertions.assertNotNull(getConfigurationBusiness().signin(
+ UserTestUtils.restUser1.getEmail(), UserTestUtils.restUser1.getPassword()));
+ }
+
+ @Test
+ public void registerEndpointWithAppOk() throws Exception {
+ String appName = "testApp", groupName = "testGroup", className = "testClass";
+ getConfigurationBusiness().addGroup(new Group(groupName, true, true, true));
+ getClassBusiness().addClass(new AppClass(className, Collections.emptyList(), List.of(groupName)));
+ getApplicationBusiness().add(new Application(appName, List.of(className), "test citation"));
+ UserTestUtils.restUser1.getApplications().add("testApp");
+ mockMvc.perform(
+ post("/rest/register").
+ content(asJsonString(UserTestUtils.restUser1))
+ .contentType(MediaType.APPLICATION_JSON)
+ .accept(MediaType.APPLICATION_JSON))
+ .andDo(print())
+ .andExpect(status().isCreated());
+ User u = getConfigurationBusiness().getUserWithGroups(UserTestUtils.restUser1.getEmail());
+ Assertions.assertEquals(1, u.getGroups().size());
+ Assertions.assertEquals(groupName, u.getGroups().iterator().next().getName());
+ }
+
+ @Test
+ public void registerEndpointValidationFailed() throws Exception {
+ UserTestUtils.restUser1.setCountryCode(null);
+ mockMvc.perform(
+ post("/rest/register") .
+ content(asJsonString(UserTestUtils.restUser1))
+ .contentType(MediaType.APPLICATION_JSON)
+ .accept(MediaType.APPLICATION_JSON))
+ .andDo(print())
+ .andExpect(status().isBadRequest())
+ .andExpect(jsonPath("$.errorCode").value(ApiException.ApiError.INPUT_FIELD_NOT_VALID.getCode()))
+ .andExpect(jsonPath("$.errorMessage").value(Matchers.containsString("'countryCode'")));
+ }
+
+
+}
\ No newline at end of file
diff --git a/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/RegisterUserControllerTest.java b/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/RegisterUserControllerTest.java
deleted file mode 100644
index 922a27f8a..000000000
--- a/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/RegisterUserControllerTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package fr.insalyon.creatis.vip.api.rest.itest;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import fr.insalyon.creatis.vip.api.data.UserTestUtils;
-import fr.insalyon.creatis.vip.api.rest.config.BaseWebSpringIT;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-import org.springframework.http.MediaType;
-
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-@Disabled
-class RegisterUserControllerTest extends BaseWebSpringIT {
-
- public static String asJsonString(final Object obj) {
- try {
- return new ObjectMapper().writeValueAsString(obj);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- @Test
- public void registerEndpointOK() throws Exception {
- mockMvc.perform(post("/rest/register")
- .content(asJsonString(UserTestUtils.restUser1))
- .contentType(MediaType.APPLICATION_JSON)
- .accept(MediaType.APPLICATION_JSON))
- .andExpect(status().isCreated());
- }
-
-}
\ No newline at end of file
diff --git a/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/SpringAuthenticationIT.java b/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/SpringAuthenticationIT.java
index 9bb89681f..d0deca203 100644
--- a/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/SpringAuthenticationIT.java
+++ b/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/SpringAuthenticationIT.java
@@ -41,7 +41,11 @@
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
import org.springframework.http.MediaType;
+import org.springframework.test.context.ContextConfiguration;
import static fr.insalyon.creatis.vip.api.data.UserTestUtils.baseUser1;
import static fr.insalyon.creatis.vip.api.data.UserTestUtils.baseUser1Password;
@@ -60,45 +64,26 @@
*
* Use common vip spring test configuration ({@link BaseWebSpringIT}
*/
-@Disabled
public class SpringAuthenticationIT extends BaseWebSpringIT {
- @Autowired
- @Qualifier("mockUserDAO")
- UserDAO userDAO;
-
- @BeforeEach
- public void setUp() throws Exception {
- super.setUp();
- Mockito.reset(userDAO);
- when(userDAO.getUserByApikey(eq("apikeyvalue"))).thenReturn(baseUser1);
- }
-
@Test
public void authenticationOK() throws Exception {
+ createUserWithPassword(emailUser2, "coucou");
+ String apikey = getConfigurationBusiness().generateNewUserApikey(emailUser2);
mockMvc.perform(get("/rest/wrongUrl")
- .with(ApikeyRequestPostProcessor.apikey("testapikey", "apikeyvalue")))
+ .with(ApikeyRequestPostProcessor.apikey("testapikey", apikey)))
.andDo(print())
.andExpect(status().isNotFound());
}
- @Test
- public void authenticationWithCoreKo() throws Exception {
- when(userDAO.getUserByApikey("apikeyvalue"))
- .thenThrow(new RuntimeException("hey hey"));
- mockMvc.perform(get("/rest/wrongUrl")
- .with(ApikeyRequestPostProcessor.apikey("testapikey", "apikeyvalue")))
- .andDo(print())
- .andExpect(status().isUnauthorized())
- .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
- .andExpect(jsonPath("$.errorCode")
- .value(ApiError.AUTHENTICATION_ERROR.getCode()));
- }
-
+ /**
+ * Basic is not supported anymore
+ */
@Test
public void authenticationWithBasicShouldBeKo() throws Exception {
+ createUserWithPassword(emailUser2, "coucou");
mockMvc.perform(get("/rest/wrongUrl")
- .with(httpBasic(baseUser1.getEmail(), baseUser1Password)))
+ .with(httpBasic(emailUser2, "coucou")))
.andDo(print())
.andExpect(status().isUnauthorized())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
diff --git a/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/SpringAuthenticationWithMockedUserDaoIT.java b/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/SpringAuthenticationWithMockedUserDaoIT.java
new file mode 100644
index 000000000..51e9d89ea
--- /dev/null
+++ b/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/SpringAuthenticationWithMockedUserDaoIT.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright and authors: see LICENSE.txt in base repository.
+ *
+ * This software is a web portal for pipeline execution on distributed systems.
+ *
+ * This software is governed by the CeCILL-B license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-B
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-B license and that you accept its terms.
+ */
+package fr.insalyon.creatis.vip.api.rest.itest;
+
+import fr.insalyon.creatis.vip.api.exception.ApiException.ApiError;
+import fr.insalyon.creatis.vip.api.rest.config.BaseWebSpringIT;
+import fr.insalyon.creatis.vip.api.tools.spring.ApikeyRequestPostProcessor;
+import fr.insalyon.creatis.vip.core.server.dao.UserDAO;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.ContextConfiguration;
+
+import static fr.insalyon.creatis.vip.api.data.UserTestUtils.baseUser1;
+import static fr.insalyon.creatis.vip.api.data.UserTestUtils.baseUser1Password;
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+/**
+ * Created by abonnet on 7/22/16.
+ *
+ * These tests check the authentication with the spring test tools.
+ * It requests a wrong url that should be secured and expects a 404 when OK
+ *
+ * Use common vip spring test configuration ({@link BaseWebSpringIT}
+ */
+@ContextConfiguration(classes = SpringAuthenticationWithMockedUserDaoIT.TestContextConfiguration.class)
+public class SpringAuthenticationWithMockedUserDaoIT extends BaseWebSpringIT {
+
+ static class TestContextConfiguration {
+ @Bean
+ @Primary
+ public UserDAO mockUser() {
+ return Mockito.mock(UserDAO.class);
+ }
+ }
+
+ @Test
+ public void authenticationWithCoreKo() throws Exception {
+ Mockito.when(getUserDAO().getUserByApikey("apikeyvalue"))
+ .thenThrow(new RuntimeException("hey hey"));
+ mockMvc.perform(get("/rest/wrongUrl")
+ .with(ApikeyRequestPostProcessor.apikey("testapikey", "apikeyvalue")))
+ .andDo(print())
+ .andExpect(status().isUnauthorized())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
+ .andExpect(jsonPath("$.errorCode")
+ .value(ApiError.AUTHENTICATION_ERROR.getCode()));
+ }
+}
diff --git a/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/processing/ExecutionControllerIT.java b/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/processing/ExecutionControllerIT.java
index 4022bf976..b0692d92d 100644
--- a/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/processing/ExecutionControllerIT.java
+++ b/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/processing/ExecutionControllerIT.java
@@ -31,39 +31,47 @@
*/
package fr.insalyon.creatis.vip.api.rest.itest.processing;
+import fr.insalyon.creatis.grida.common.bean.GridData;
import fr.insalyon.creatis.moteur.plugins.workflowsdb.bean.*;
import fr.insalyon.creatis.moteur.plugins.workflowsdb.dao.InputDAO;
import fr.insalyon.creatis.moteur.plugins.workflowsdb.dao.OutputDAO;
import fr.insalyon.creatis.moteur.plugins.workflowsdb.dao.WorkflowDAO;
+import fr.insalyon.creatis.moteur.plugins.workflowsdb.dao.WorkflowsDBDAOException;
import fr.insalyon.creatis.vip.api.exception.ApiException;
+import fr.insalyon.creatis.vip.api.model.Execution;
+import fr.insalyon.creatis.vip.api.model.ExecutionStatus;
import fr.insalyon.creatis.vip.api.rest.config.BaseWebSpringIT;
import fr.insalyon.creatis.vip.api.rest.config.RestTestUtils;
import fr.insalyon.creatis.vip.application.client.bean.AppClass;
import fr.insalyon.creatis.vip.application.client.bean.AppVersion;
import fr.insalyon.creatis.vip.application.client.bean.Application;
import fr.insalyon.creatis.vip.application.client.bean.Engine;
+import fr.insalyon.creatis.vip.application.client.view.monitor.SimulationStatus;
+import fr.insalyon.creatis.vip.application.server.business.simulation.ParameterSweep;
import fr.insalyon.creatis.vip.application.server.business.simulation.WebServiceEngine;
-import fr.insalyon.creatis.vip.application.server.dao.ApplicationDAO;
import fr.insalyon.creatis.vip.core.client.bean.Group;
-import fr.insalyon.creatis.vip.core.server.business.BusinessException;
-import fr.insalyon.creatis.vip.core.server.dao.GroupDAO;
-import fr.insalyon.creatis.vip.core.server.dao.UsersGroupsDAO;
+import fr.insalyon.creatis.vip.core.integrationtest.ServerMockConfig;
+import org.hamcrest.MatcherAssert;
+import org.hamcrest.Matchers;
+import org.hibernate.jdbc.Work;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatchers;
+import org.mockito.MockedConstruction;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType;
-import org.springframework.test.web.servlet.MvcResult;
-import org.springframework.test.web.servlet.ResultActions;
+import java.io.File;
+import java.lang.reflect.Parameter;
import java.util.*;
import static fr.insalyon.creatis.vip.api.data.ExecutionTestUtils.*;
import static fr.insalyon.creatis.vip.api.data.UserTestUtils.baseUser1;
-import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.*;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
@@ -77,27 +85,6 @@
*/
public class ExecutionControllerIT extends BaseWebSpringIT {
- @Autowired
- @Qualifier("mockWorkflowDAO")
- WorkflowDAO workflowDAO;
- @Autowired
- @Qualifier("mockOutputDAO")
- OutputDAO outputDAO;
- @Autowired
- @Qualifier("mockInputDAO")
- InputDAO inputDAO;
- //@Autowired
- //@Qualifier("mockUsersGroupsDAO")
- UsersGroupsDAO usersGroupsDAO;
- //@Autowired
- //@Qualifier("mockApplicationDAO")
- ApplicationDAO applicationDAO;
- @Autowired
- @Qualifier("mockWebServiceEngine")
- WebServiceEngine webServiceEngine;
- //@Autowired
- //@Qualifier("mockGroupDAO")
- GroupDAO groupDAO;
private Workflow w1;
private Workflow w2;
@@ -105,12 +92,6 @@ public class ExecutionControllerIT extends BaseWebSpringIT {
@BeforeEach
public void setUp() throws Exception {
super.setUp();
- Mockito.reset(workflowDAO);
- Mockito.reset(outputDAO);
- Mockito.reset(webServiceEngine);
- Mockito.reset(inputDAO);
- //Mockito.reset(usersGroupsDAO);
- //Mockito.reset(applicationDAO);
w1 = new Workflow(simulation1.getID(), baseUser1.getFullName(), WorkflowStatus.Completed, new Date(), new Date(), "description", "application", "applicationVersion", "applicationClass", "engine");
w2 = new Workflow(simulation2.getID(), baseUser1.getFullName(), WorkflowStatus.Completed, new Date(), new Date(), "description", "application", "applicationVersion", "applicationClass", "engine");
@@ -120,7 +101,8 @@ public void setUp() throws Exception {
public void shouldListExecutions() throws Exception {
when(workflowDAO.get(eq(simulation1.getID()))).thenReturn(w1, null);
when(workflowDAO.get(eq(simulation2.getID()))).thenReturn(w2, null);
- when(workflowDAO.get(eq(baseUser1.getFullName()), ArgumentMatchers.isNull(), ArgumentMatchers.isNull(), ArgumentMatchers.isNull(), ArgumentMatchers.isNull(), ArgumentMatchers.isNull()))
+ when(workflowDAO.get(
+ eq(baseUser1.getFullName()), ArgumentMatchers.isNull(), ArgumentMatchers.isNull(), ArgumentMatchers.isNull(), ArgumentMatchers.isNull(), ArgumentMatchers.isNull()))
.thenReturn(Arrays.asList(w1, w2), null);
// perform a getWorkflows()
@@ -129,7 +111,7 @@ public void shouldListExecutions() throws Exception {
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
- .andExpect(jsonPath("[*]", hasSize(2)))
+ .andExpect(jsonPath("$[*]", hasSize(2)))
// Check that the returned executions are the good ones
.andExpect(jsonPath("$[0].status").value("Finished"))
.andExpect(jsonPath("$[0].identifier").value("execId1"))
@@ -183,13 +165,19 @@ public void shouldGetExecution2() throws Exception {
}
@Test
- public void shouldGetErrorWhenGettingUnknownExecution() throws Exception {
- when(workflowDAO.get(argThat(argument -> !simulation1.getID().equals(argument) && !simulation2.getID().equals(argument))))
- .thenAnswer(invocation -> {
- throw new BusinessException("no test execution");
- });
+ public void shouldGetErrorOnUnknownExecution() throws Exception {
+ mockMvc.perform(
+ get("/rest/executions/WrongExecId").with(baseUser1()))
+ .andDo(print())
+ .andExpect(status().isBadRequest())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
+ .andExpect(jsonPath("$.errorCode").value(ApiException.ApiError.GENERIC_API_ERROR.getCode()));
+ }
+
+ @Test
+ public void shouldGetErrorOnExpectedException() throws Exception {
+ when(workflowDAO.get(anyString())).thenThrow(new WorkflowsDBDAOException("test exception"));
- // perform a getWorkflows()
mockMvc.perform(
get("/rest/executions/WrongExecId").with(baseUser1()))
.andDo(print())
@@ -200,10 +188,7 @@ public void shouldGetErrorWhenGettingUnknownExecution() throws Exception {
@Test
public void shouldReturnErrorOnUnexpectedException() throws Exception {
- when(workflowDAO.get(argThat(argument -> !simulation1.getID().equals(argument) && !simulation2.getID().equals(argument))))
- .thenAnswer(invocation -> {
- throw new RuntimeException("TEST RUNTIME EXCEPTION");
- });
+ when(workflowDAO.get(anyString())).thenThrow(new RuntimeException("TEST RUNTIME EXCEPTION"));
// perform a getWorkflows()
mockMvc.perform(
@@ -345,25 +330,26 @@ public void testPlayExecutionIsNotImplemented() throws Exception {
}
@Test
- @Disabled
public void shouldGetExecution2Results() throws Exception {
- String resultPath = simulation2OutData.get(0).getPath();
+ String resultPath = "/root/user/user1/path/to/result.res";
+
when(workflowDAO.get(eq(simulation2.getID()))).thenReturn(w2, null);
Output output = new Output(new OutputID("workflowID", resultPath, "processor"), DataType.URI, "port");
when(outputDAO.get(eq(simulation2.getID()))).thenReturn(Arrays.asList(output), null);
- Group group = new Group("group1", true, true, true);
- configurationBusiness.addGroup(group);
- when(groupDAO.getGroups()).thenReturn(Arrays.asList(group));
+ Mockito.when(server.getDataManagerUsersHome()).thenReturn("/root/user");
+ Mockito.when(gridaClient.exist(resultPath)).thenReturn(true);
+ Mockito.when(gridaClient.getFolderData(resultPath, true)).thenReturn(Arrays.asList(
+ new GridData("result.res", GridData.Type.File, 42, "modifData", "", "", "")));
mockMvc.perform(
get("/rest/executions/" + simulation2.getID() + "/results").with(baseUser1()))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
- .andExpect(jsonPath("$[*]", hasSize(1)));
- /*.andExpect(jsonPath("$[0]",
- PathTestUtils.jsonCorrespondsToPath(PathTestUtils.testFile1PathProperties)));*/
+ .andExpect(jsonPath("$[*]", hasSize(1)))
+ .andExpect(jsonPath("$[0].path", equalTo("/vip/Home/path/to/result.res")))
+ .andExpect(jsonPath("$[0].size", equalTo(42)));
}
@@ -380,63 +366,158 @@ public void shouldKillExecution2() throws Exception
}
@Test
- @Disabled
- public void testInitExecution() throws Exception
+ public void testInitGwendiaExecution() throws Exception
{
- // engine test creation
- group1 = new Group("group1", true, true, true);
- configurationBusiness.addGroup(group1);
- List groups = new ArrayList<>();
- groups.add("group1");
- createUserInGroup("test1@test.fr", "suffix1", "group1");
- createUserInGroup("test2@test.fr", "suffix2", "group1");
-
- // engine test creation
- String engineName = "test engine";
- String engineEndpoint = "test endpoint";
- String engineStatus = "enabled";
- Engine engine = new Engine(engineName, engineEndpoint, engineStatus);
- List engines = new ArrayList<>();
- engines.add("test engine");
- engineBusiness.add(engine);
-
- // appClass test creation
- AppClass appClass = new AppClass("class1", engines, groups);
- classBusiness.addClass(appClass);
- applicationClasses = new ArrayList<>();
- applicationClasses.add("class1");
-
- // Application test creation
- Application application = new Application("application 1", applicationClasses, "test1@test.fr", "test1", "citation1");
- applicationBusiness.add(application);
-
- // AppVersion test creation
- AppVersion version42 = new AppVersion("application 1", "version 4.2", "lfn", "jsonLfn", true, true);
- applicationBusiness.addVersion(version42);
-
- when(applicationDAO.getApplication("application 1")).thenReturn(application);
-
- // configure lauch
- when(workflowDAO.get(eq(simulation1.getID()))).thenReturn(w1);
- when(workflowDAO.getNumberOfRunning(baseUser1.getFullName())).thenReturn(1L);
- when(workflowDAO.getRunning()).thenReturn(Arrays.asList(w1));
- when(applicationDAO.getVersion("Application 1", "version 0.0")).thenReturn(version42);
- Input input = new Input(new InputID("workflowId", "jsonObjects/execution1.json", "processor"), DataType.URI);
- when(inputDAO.get(eq(simulation1.getID()))).thenReturn(Arrays.asList(input));
- //when(testLfcPathsBusiness.parseRealDir(anyString(), eq(baseUser1.getFolder()))).thenReturn("path",null);
- Output output = new Output(new OutputID("workflowID", "path", "processor"), DataType.URI, "port");
- when(outputDAO.get(eq(simulation1.getID()))).thenReturn(Arrays.asList(output));
- when(usersGroupsDAO.getUserGroups(eq(baseUser1.getEmail()))).thenReturn(new HashMap<>());
+ String appName = "test application", groupName = "testGroup", className = "testClass", versionName = "4.2";
+ String engineName = "testEngine", engineEndpoint = "endpoint", worflowId = "test-workflow-id";
+ Date startDate = new Date();
+
+ configureGwendiaTestApp(appName,groupName, className, versionName);
+ addEngineToClass(className, engineName, engineEndpoint);
+
+ createUserInGroup(baseUser1.getEmail(), groupName);
+
+ ArgumentCaptor workflowFile = ArgumentCaptor.forClass(File.class);
+ ArgumentCaptor> inputsCaptor = ArgumentCaptor.forClass(List.class);
+ ArgumentCaptor workflowCaptor = ArgumentCaptor.forClass(Workflow.class);
+
+ Mockito.when(server.getVoName()).thenReturn("test-vo-name");
+ Mockito.when(server.getServerProxy("test-vo-name")).thenReturn("/path/to/proxy");
+ Mockito.when(getWebServiceEngine().launch("/path/to/proxy", null)).thenReturn("full-test-workflow-id", (String) null);
+ Mockito.when(getWebServiceEngine().getSimulationId("full-test-workflow-id")).thenReturn(worflowId, (String) null);
+ Mockito.when(getWebServiceEngine().getStatus(worflowId)).thenReturn(SimulationStatus.Running, (SimulationStatus) null);
+ Mockito.when(getWebServiceEngine().getAddressWS()).thenReturn(engineEndpoint, (String) null);
+
+ Workflow w = new Workflow(worflowId, baseUser1.getFullName(), WorkflowStatus.Running, startDate, null, "Exec test 1", appName, versionName, className, engineName);
+ when(workflowDAO.get(worflowId)).thenReturn(w, (Workflow) null);
+
+ Execution expectedExecution = new Execution(worflowId, "Exec test 1", appName + "/" + versionName, 0, ExecutionStatus.RUNNING, null, null, startDate.getTime(), null, null);
+ expectedExecution.clearReturnedFiles();
mockMvc.perform(
- post("/rest/executions").contentType("application/json")
- .content(getResourceAsString("jsonObjects/execution1.json"))
- .with(baseUser1()))
- .andDo(print())
- .andExpect(status().isOk())
- .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
- .andExpect(jsonPath("$",
- jsonCorrespondsToExecution(execution1)
+ post("/rest/executions").contentType("application/json")
+ .content(getResourceAsString("jsonObjects/execution1.json"))
+ .with(baseUser1()))
+ .andDo(print())
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
+ .andExpect(jsonPath("$",
+ jsonCorrespondsToExecution(expectedExecution)
+ ));
+
+ // verify workflow path
+ Mockito.verify(getWebServiceEngine()).setWorkflow(workflowFile.capture());
+ Assertions.assertEquals(getGwendiaTestFile().getAbsolutePath(), workflowFile.getValue().getAbsolutePath());
+
+ // verify inputs
+ Mockito.verify(getWebServiceEngine()).setInput(inputsCaptor.capture());
+ List inputs = inputsCaptor.getValue();
+ Assertions.assertEquals(5, inputs.size());
+ MatcherAssert.assertThat(inputs, Matchers.containsInAnyOrder(
+ both(hasProperty("parameterName", is("testFileInput"))).
+ and(hasProperty("values", Matchers.contains(ServerMockConfig.TEST_USERS_ROOT + "/" + baseUser1.getFolder() + "/path/to/input.in"))),
+ both(hasProperty("parameterName", is("testTextInput"))).
+ and(hasProperty("values", Matchers.contains("best test text value"))),
+ both(hasProperty("parameterName", is("results-directory"))).
+ and(hasProperty("values", Matchers.contains(ServerMockConfig.TEST_USERS_ROOT + "/" + baseUser1.getFolder()))),
+ both(hasProperty("parameterName", is("testOptionalTextInput"))).
+ and(hasProperty("values", Matchers.contains("No_value_provided"))),
+ both(hasProperty("parameterName", is("testFlagInput"))).
+ and(hasProperty("values", Matchers.contains("false")))
));
+
+ // verify created workflow
+ Mockito.verify(workflowDAO).add(workflowCaptor.capture());
+ Workflow workflow = workflowCaptor.getValue();
+ Assertions.assertEquals(appName, workflow.getApplication());
+ Assertions.assertEquals(versionName, workflow.getApplicationVersion());
+ Assertions.assertEquals(className, workflow.getApplicationClass());
+ Assertions.assertEquals(worflowId, workflow.getId());
+ Assertions.assertEquals(WorkflowStatus.Running, workflow.getStatus());
+ Assertions.assertEquals("Exec test 1", workflow.getDescription());
+ Assertions.assertEquals(engineEndpoint, workflow.getEngine());
+ Assertions.assertEquals(baseUser1.getFullName(), workflow.getUsername());
+ Assertions.assertNull(workflow.getFinishedTime());
+ MatcherAssert.assertThat(workflow.getStartedTime().getTime(),
+ is(both(greaterThan(startDate.getTime())).and(lessThan(new Date().getTime()))));
+
+ }
+
+ // the difference (at the moment) is that with moteurLite the optional and absent parameters are not included
+ @Test
+ public void testInitBoutiquesExecution() throws Exception
+ {
+ String appName = "test application", groupName = "testGroup", className = "testClass", versionName = "4.2";
+ String engineName = "testEngine", engineEndpoint = "endpoint", worflowId = "test-workflow-id";
+ Date startDate = new Date();
+
+ configureBoutiquesTestApp(appName,groupName, className, versionName);
+ addEngineToClass(className, engineName, engineEndpoint);
+
+ createUserInGroup(baseUser1.getEmail(), groupName);
+
+ ArgumentCaptor workflowFile = ArgumentCaptor.forClass(File.class);
+ ArgumentCaptor> inputsCaptor = ArgumentCaptor.forClass(List.class);
+ ArgumentCaptor workflowCaptor = ArgumentCaptor.forClass(Workflow.class);
+
+ Mockito.when(server.useMoteurlite()).thenReturn(true);
+ Mockito.when(server.getVoName()).thenReturn("test-vo-name");
+ Mockito.when(server.getServerProxy("test-vo-name")).thenReturn("/path/to/proxy");
+ Mockito.when(getWebServiceEngine().launch("/path/to/proxy", null)).thenReturn("full-test-workflow-id", (String) null);
+ Mockito.when(getWebServiceEngine().getSimulationId("full-test-workflow-id")).thenReturn(worflowId, (String) null);
+ Mockito.when(getWebServiceEngine().getStatus(worflowId)).thenReturn(SimulationStatus.Running, (SimulationStatus) null);
+ Mockito.when(getWebServiceEngine().getAddressWS()).thenReturn(engineEndpoint, (String) null);
+
+ Workflow w = new Workflow(worflowId, baseUser1.getFullName(), WorkflowStatus.Running, startDate, null, "Exec test 1", appName, versionName, className, engineName);
+ when(workflowDAO.get(worflowId)).thenReturn(w, (Workflow) null);
+
+ Execution expectedExecution = new Execution(worflowId, "Exec test 1", appName + "/" + versionName, 0, ExecutionStatus.RUNNING, null, null, startDate.getTime(), null, null);
+ expectedExecution.clearReturnedFiles();
+
+ mockMvc.perform(
+ post("/rest/executions").contentType("application/json")
+ .content(getResourceAsString("jsonObjects/execution1.json"))
+ .with(baseUser1()))
+ .andDo(print())
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
+ .andExpect(jsonPath("$",
+ jsonCorrespondsToExecution(expectedExecution)
+ ));
+
+ // verify workflow path
+ Mockito.verify(getWebServiceEngine()).setWorkflow(workflowFile.capture());
+ Assertions.assertEquals(getBoutiquesTestFile().getAbsolutePath(), workflowFile.getValue().getAbsolutePath());
+
+ // verify inputs
+ Mockito.verify(getWebServiceEngine()).setInput(inputsCaptor.capture());
+ List inputs = inputsCaptor.getValue();
+ Assertions.assertEquals(4, inputs.size());
+ MatcherAssert.assertThat(inputs, Matchers.containsInAnyOrder(
+ both(hasProperty("parameterName", is("testFileInput"))).
+ and(hasProperty("values", Matchers.contains(ServerMockConfig.TEST_USERS_ROOT + "/" + baseUser1.getFolder() + "/path/to/input.in"))),
+ both(hasProperty("parameterName", is("testTextInput"))).
+ and(hasProperty("values", Matchers.contains("best test text value"))),
+ both(hasProperty("parameterName", is("results-directory"))).
+ and(hasProperty("values", Matchers.contains(ServerMockConfig.TEST_USERS_ROOT + "/" + baseUser1.getFolder()))),
+ both(hasProperty("parameterName", is("testFlagInput"))).
+ and(hasProperty("values", Matchers.contains("false")))
+ ));
+
+ // verify created workflow
+ Mockito.verify(workflowDAO).add(workflowCaptor.capture());
+ Workflow workflow = workflowCaptor.getValue();
+ Assertions.assertEquals(appName, workflow.getApplication());
+ Assertions.assertEquals(versionName, workflow.getApplicationVersion());
+ Assertions.assertEquals(className, workflow.getApplicationClass());
+ Assertions.assertEquals(worflowId, workflow.getId());
+ Assertions.assertEquals(WorkflowStatus.Running, workflow.getStatus());
+ Assertions.assertEquals("Exec test 1", workflow.getDescription());
+ Assertions.assertEquals(engineEndpoint, workflow.getEngine());
+ Assertions.assertEquals(baseUser1.getFullName(), workflow.getUsername());
+ Assertions.assertNull(workflow.getFinishedTime());
+ MatcherAssert.assertThat(workflow.getStartedTime().getTime(),
+ is(both(greaterThan(startDate.getTime())).and(lessThan(new Date().getTime()))));
+
}
}
diff --git a/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/processing/PipelineControllerIT.java b/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/processing/PipelineControllerIT.java
index 9f3ce0e14..a47622aee 100644
--- a/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/processing/PipelineControllerIT.java
+++ b/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/itest/processing/PipelineControllerIT.java
@@ -31,75 +31,32 @@
*/
package fr.insalyon.creatis.vip.api.rest.itest.processing;
-import fr.insalyon.creatis.vip.api.data.ClassesTestUtils;
-import fr.insalyon.creatis.vip.api.data.UserTestUtils;
+import fr.insalyon.creatis.grida.client.GRIDAClientException;
import fr.insalyon.creatis.vip.api.exception.ApiException.ApiError;
import fr.insalyon.creatis.vip.api.rest.config.BaseWebSpringIT;
-import fr.insalyon.creatis.vip.application.client.bean.AppClass;
import fr.insalyon.creatis.vip.application.client.bean.AppVersion;
-import fr.insalyon.creatis.vip.application.client.bean.Application;
-import fr.insalyon.creatis.vip.application.server.dao.ApplicationDAO;
-import fr.insalyon.creatis.vip.application.server.dao.ClassDAO;
-import fr.insalyon.creatis.vip.core.client.bean.Group;
import fr.insalyon.creatis.vip.core.server.business.BusinessException;
-import fr.insalyon.creatis.vip.datamanager.server.business.DataManagerBusiness;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType;
-import org.springframework.test.web.servlet.MvcResult;
-import org.springframework.test.web.servlet.ResultActions;
-import org.springframework.test.web.servlet.request.RequestPostProcessor;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
+import java.io.File;
+import java.io.IOException;
-import static fr.insalyon.creatis.vip.api.data.AppVersionTestUtils.*;
-import static fr.insalyon.creatis.vip.api.data.ApplicationTestUtils.*;
import static fr.insalyon.creatis.vip.api.data.PipelineTestUtils.*;
-import static fr.insalyon.creatis.vip.api.data.UserTestUtils.baseUser1;
-import static fr.insalyon.creatis.vip.api.rest.mockconfig.ApplicationsConfigurator.configureAnApplication;
-import static fr.insalyon.creatis.vip.api.rest.mockconfig.ApplicationsConfigurator.configureApplications;
+import static fr.insalyon.creatis.vip.api.data.UserTestUtils.*;
import static fr.insalyon.creatis.vip.application.client.view.ApplicationException.ApplicationError.WRONG_APPLICATION_DESCRIPTOR;
-import static org.hamcrest.Matchers.containsInAnyOrder;
-import static org.hamcrest.Matchers.hasSize;
-import static org.mockito.ArgumentMatchers.*;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.when;
+import static org.hamcrest.Matchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
-/**
- * Created by abonnet on 7/20/16.
- *
- * Test methods on pipeline path
- *
- * Include 2 tests on error handling
- */
-@Disabled
public class PipelineControllerIT extends BaseWebSpringIT {
- @Autowired
- @Qualifier("mockClassDAO")
- ClassDAO classDAO;
- @Autowired
- @Qualifier("mockApplicationDAO")
- ApplicationDAO applicationDAO;
- @Autowired
- @Qualifier("mockDataManagerBusiness")
- DataManagerBusiness dataManagerBusiness;
-
@BeforeEach
public void setUp() throws Exception {
super.setUp();
- Mockito.reset(classDAO);
- Mockito.reset(applicationDAO);
}
@Test
@@ -129,13 +86,22 @@ public void shouldReturnErrorOnAPIExceptionInvalidId() throws Exception {
@Test
public void shouldReturnErrorOnConfiguredVipException() throws Exception {
- /*configureApplications(this, baseUser1, Arrays.asList(class1, class2),
- app2, version42);*/
+ String appName = "testApp", groupName = "testGroup", className = "testClass";
+ String versionName = "42-test";
+ AppVersion appVersion = configureAnApplication(appName, versionName, groupName, className);
+ configureVersion(appVersion,
+ "/vip/testGroup (group)/path/to/test.gwendia", null);
+
+ createUserInGroup(baseUser1.getEmail(), groupName);
+
+ Mockito.when(server.getDataManagerPath()).thenReturn("/test/folder");
+ Mockito.when(server.getDataManagerGroupsHome()).thenReturn("/root/group");
+ // localDir is datamanagerpath + "downloads" + groupRoot + dir(path)
+ Mockito.when(gridaClient.getRemoteFile(
+ "/root/group/testGroup/path/to/test.gwendia",
+ "/test/folder/downloads/root/group/testGroup/path/to")).thenThrow(new GRIDAClientException("test exception"));
- String pipelineId = app2.getName() + "/" + version42.getVersion();
- when(workflowBusiness.getApplicationDescriptor(
- eq(baseUser1), eq(app2.getName()), eq(version42.getVersion())))
- .thenThrow(new BusinessException(WRONG_APPLICATION_DESCRIPTOR, pipelineId));
+ String pipelineId = appName + "/" + versionName;
mockMvc.perform(get("/rest/pipelines/" + pipelineId).with(baseUser1()))
.andDo(print())
.andExpect(status().isBadRequest())
@@ -145,74 +111,155 @@ public void shouldReturnErrorOnConfiguredVipException() throws Exception {
@Test
public void userGetAPipelineWithPathParameterNonEncoded() throws Exception {
- /*configureApplications(this, baseUser1, Arrays.asList(class1, class2),
- app2, version42);*/
- String pipelineId = configureAnApplication(this, baseUser1, app2, version42, 0, 1);
- mockMvc.perform(get("/rest/pipelines/" + pipelineId)
- .with(baseUser1()))
+ String appName = "testGwendiaApp", groupName = "testGroup", className = "testClass", versionName = "42-test";
+ AppVersion appVersion = configureGwendiaTestApp(appName, groupName, className, versionName);
+ String pipelineId = appName + "/" + versionName;
+
+ createUserInGroup(baseUser1.getEmail(), groupName);
+
+ mockMvc.perform(get("/rest/pipelines/" + pipelineId).with(baseUser1()))
.andDo(print())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
- .andExpect(jsonPath("$", jsonCorrespondsToPipeline(getFullPipeline(app2, version42, "desc test", 0, 1))));
+ // res-dir should be removed from the description
+ .andExpect(jsonPath("$", jsonCorrespondsToPipeline(
+ getFullPipeline(appVersion, "Test tool description. Must be similar to the boutiques one", flagParam, textParam, fileParam, optionalTextParamNoValueProvided))));
}
@Test
- public void shouldReturnPipelines() throws Exception {
+ public void userGetAPipelineWithQueryParameter() throws Exception {
+ String appName = "testGwendiaApp", groupName = "testGroup", className = "testClass", versionName = "42-test";
+ AppVersion appVersion = configureGwendiaTestApp(appName, groupName, className, versionName);
+ String pipelineId = appName + "/" + versionName;
+
+ createUserInGroup(baseUser1.getEmail(), groupName);
+
+ mockMvc.perform(get("/rest/pipelines").param("pipelineId", pipelineId).with(baseUser1()))
+ .andDo(print())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
+ // res-dir should be removed from the description
+ .andExpect(jsonPath("$", jsonCorrespondsToPipeline(
+ getFullPipeline(appVersion, "Test tool description. Must be similar to the boutiques one", flagParam, textParam, fileParam, optionalTextParamNoValueProvided))));
+ }
- AppClass appClass = new AppClass("appClass", new ArrayList<>());
- classBusiness.addClass(appClass);
+ @Test
+ public void userGetAPipelineWithBoutiques() throws Exception {
- createUser("test1@test.fr");
+ String appName = "testBoutiquesApp", groupName = "testGroup", className = "testClass", versionName = "v42";
+ AppVersion appVersion = configureBoutiquesTestApp(appName, groupName, className, versionName);
+ String pipelineId = appName + "/" + versionName;
- Application app1 = new Application("app1", Arrays.asList(appClass.getName()), "test1@test.fr", "test1", "citation1");
- Application app2 = new Application("app2", Arrays.asList(appClass.getName()), "test1@test.fr", "test1", "citation1");
- Application app3 = new Application("app3", Arrays.asList(appClass.getName()), "test1@test.fr", "test1", "citation1");
- applicationBusiness.add(app1);
- applicationBusiness.add(app2);
- applicationBusiness.add(app3);
+ Mockito.when(server.useMoteurlite()).thenReturn(true);
- AppVersion version42App1 = new AppVersion("app1", "version42", "lfn", "jsonLfn", true, true);
- applicationBusiness.addVersion(version42App1);
+ createUserInGroup(baseUser1.getEmail(), groupName);
- AppVersion version42App3 = new AppVersion("app3", "version42", "lfn", "jsonLfn", true, true);
- applicationBusiness.addVersion(version42App3);
+ mockMvc.perform(get("/rest/pipelines/" + pipelineId).with(baseUser1()))
+ .andDo(print())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
+ // res-dir should be absent from the description
+ .andExpect(jsonPath("$.name", equalTo(appName)))
+ .andExpect(jsonPath("$", jsonCorrespondsToPipeline(
+ getFullPipeline(appVersion, "Test app from axel. Must be similar to the gwendia test app", flagParam, textParam, fileParam, optionalTextParam))));
- AppVersion version01App2= new AppVersion("app2", "version01", "lfn", "jsonLfn", true, true);
- applicationBusiness.addVersion(version01App2);
+ }
- AppVersion version01App3= new AppVersion("app3", "version01", "lfn", "jsonLfn", true, true);
- applicationBusiness.addVersion(version01App3);
+ @Test
+ public void userGetBoutiquesDescriptor() throws Exception {
- AppVersion version43App3= new AppVersion("app3", "version43", "lfn", "jsonLfn", true, true);
- applicationBusiness.addVersion(version43App3);
+ String appName = "testBoutiquesApp", groupName = "testGroup", className = "testClass", versionName = "v42";
+ configureBoutiquesTestApp(appName, groupName, className, versionName);
+ String pipelineId = appName + "/" + versionName;
+ createUserInGroup(baseUser1.getEmail(), groupName);
- ResultActions result = mockMvc.perform(get("/rest/pipelines").with(baseUser1()))
+ mockMvc.perform(get("/rest/pipelines/" + pipelineId).param("format", "boutiques").with(baseUser1()))
.andDo(print())
- .andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
- .andExpect(jsonPath("$[*]", hasSize(5)))
- .andExpect(jsonPath("$[*]", containsInAnyOrder(
- jsonCorrespondsToPipeline(getPipeline(app1, version42)),
- jsonCorrespondsToPipeline(getPipeline(app2, version01)),
- jsonCorrespondsToPipeline(getPipeline(app3, version01)),
- jsonCorrespondsToPipeline(getPipeline(app3, version42)),
- jsonCorrespondsToPipeline(getPipeline(app3, version43)))));
-
- String content = result.andReturn().getResponse().getContentAsString();
- System.out.println("Results : "+content);
+ // res-dir should be removed from the description
+ .andExpect(jsonPath("$.name", equalTo(appName)))
+ .andExpect(jsonPath("$.tool-version", equalTo(versionName)))
+ .andExpect(jsonPath("$.schema-version", equalTo("0.5")))
+ .andExpect(jsonPath("$.inputs[*]", hasSize(4)));
+
}
@Test
- public void userGetAPipelineWithQueryParameter() throws Exception {
- /*configureApplications(this, baseUser1, Arrays.asList(class1, class2),
- app2, version42);*/
+ public void shouldReturnPipelines() throws Exception {
+ createGroup("group1");
+ createGroup("group2");
+ createGroup("group3");
- String pipelineId = configureAnApplication(this, baseUser1, app2, version42, 0, 1);
- mockMvc.perform(get("/rest/pipelines").param("pipelineId", pipelineId)
- .with(baseUser1()))
+ createClass("class1", "group1");
+ createClass("class2", "group2");
+ createClass("class3", "group3");
+ createAnApplication("app1", "class1");
+ createAnApplication("app2", "class2");
+ createAnApplication("app3", "class3");
+
+ AppVersion app11 = createAVersion("app1", "v1", true, null, null);
+ createAVersion("app1", "v2", false, null, null);
+ AppVersion app13 = createAVersion("app1", "v3", true, null, null);
+ AppVersion app2 = createAVersion("app2", "v1.1", true, null, null);
+ createAVersion("app3", "v4", false, null, null);
+
+ createClass("classA", "group1", "group2");
+ createClass("classB", "group2", "group3");
+ createClass("classC", "group3");
+
+ createAnApplication("appAB", "classA", "classB");
+ createAnApplication("appBC", "classB", "classC");
+ createAnApplication("appC", "classC");
+
+ AppVersion appAB = createAVersion("appAB", "v1", true, null, null);
+ AppVersion appBC = createAVersion("appBC", "v1", true, null, null);
+ AppVersion appC = createAVersion("appC", "v1", true, null, null);
+
+ createUserInGroup(baseUser1.getEmail(), "test1", "group1");
+ createUserInGroup(baseUser2.getEmail(), "test2", "group2");
+ createUserInGroup(baseUser3.getEmail(), "test3", "group3");
+ createUserInGroups(baseUser4.getEmail(), "test4", "group1", "group2");
+
+ mockMvc.perform(get("/rest/pipelines").with(baseUser1()))
.andDo(print())
+ .andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
- .andExpect(jsonPath("$", jsonCorrespondsToPipeline(getFullPipeline(app2, version42, "desc test", 0, 1))));
+ .andExpect(jsonPath("$[*]", hasSize(3)))
+ .andExpect(jsonPath("$[*]", containsInAnyOrder(
+ jsonCorrespondsToPipeline(getPipeline(app11)),
+ jsonCorrespondsToPipeline(getPipeline(app13)),
+ jsonCorrespondsToPipeline(getPipeline(appAB)))));
+
+ mockMvc.perform(get("/rest/pipelines").with(baseUser2()))
+ .andDo(print())
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
+ .andExpect(jsonPath("$[*]", hasSize(3)))
+ .andExpect(jsonPath("$[*]", containsInAnyOrder(
+ jsonCorrespondsToPipeline(getPipeline(app2)),
+ jsonCorrespondsToPipeline(getPipeline(appAB)),
+ jsonCorrespondsToPipeline(getPipeline(appBC)))));
+
+ mockMvc.perform(get("/rest/pipelines").with(baseUser3()))
+ .andDo(print())
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
+ .andExpect(jsonPath("$[*]", hasSize(3)))
+ .andExpect(jsonPath("$[*]", containsInAnyOrder(
+ jsonCorrespondsToPipeline(getPipeline(appAB)),
+ jsonCorrespondsToPipeline(getPipeline(appBC)),
+ jsonCorrespondsToPipeline(getPipeline(appC)))));
+
+ mockMvc.perform(get("/rest/pipelines").with(baseUser4()))
+ .andDo(print())
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
+ .andExpect(jsonPath("$[*]", hasSize(5)))
+ .andExpect(jsonPath("$[*]", containsInAnyOrder(
+ jsonCorrespondsToPipeline(getPipeline(app11)),
+ jsonCorrespondsToPipeline(getPipeline(app13)),
+ jsonCorrespondsToPipeline(getPipeline(app2)),
+ jsonCorrespondsToPipeline(getPipeline(appAB)),
+ jsonCorrespondsToPipeline(getPipeline(appBC)))));
+
}
}
diff --git a/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/mockconfig/ApplicationsConfigurator.java b/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/mockconfig/ApplicationsConfigurator.java
deleted file mode 100644
index 4f16fc608..000000000
--- a/vip-api/src/test/java/fr/insalyon/creatis/vip/api/rest/mockconfig/ApplicationsConfigurator.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright and authors: see LICENSE.txt in base repository.
- *
- * This software is a web portal for pipeline execution on distributed systems.
- *
- * This software is governed by the CeCILL-B license under French law and
- * abiding by the rules of distribution of free software. You can use,
- * modify and/ or redistribute the software under the terms of the CeCILL-B
- * license as circulated by CEA, CNRS and INRIA at the following URL
- * "http://www.cecill.info".
- *
- * As a counterpart to the access to the source code and rights to copy,
- * modify and redistribute granted by the license, users are provided only
- * with a limited warranty and the software's author, the holder of the
- * economic rights, and the successive licensors have only limited
- * liability.
- *
- * In this respect, the user's attention is drawn to the risks associated
- * with loading, using, modifying and/or developing or reproducing the
- * software by the user in light of its specific status of free software,
- * that may mean that it is complicated to manipulate, and that also
- * therefore means that it is reserved for developers and experienced
- * professionals having in-depth computer knowledge. Users are therefore
- * encouraged to load and test the software's suitability as regards their
- * requirements in conditions enabling the security of their systems and/or
- * data to be ensured and, more generally, to use and operate it in the
- * same conditions as regards security.
- *
- * The fact that you are presently reading this means that you have had
- * knowledge of the CeCILL-B license and that you accept its terms.
- */
-package fr.insalyon.creatis.vip.api.rest.mockconfig;
-
-import fr.insalyon.creatis.vip.api.rest.config.BaseWebSpringIT;
-import fr.insalyon.creatis.vip.application.client.bean.AppClass;
-import fr.insalyon.creatis.vip.application.client.bean.AppVersion;
-import fr.insalyon.creatis.vip.application.client.bean.Application;
-import fr.insalyon.creatis.vip.application.server.business.ApplicationBusiness;
-import fr.insalyon.creatis.vip.application.server.business.ClassBusiness;
-import fr.insalyon.creatis.vip.application.server.business.WorkflowBusiness;
-import fr.insalyon.creatis.vip.core.client.bean.User;
-import fr.insalyon.creatis.vip.core.server.business.BusinessException;
-
-import java.util.*;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-import static fr.insalyon.creatis.vip.api.data.AppVersionTestUtils.getVersion;
-import static fr.insalyon.creatis.vip.api.data.PipelineTestUtils.getDescriptor;
-import static org.mockito.ArgumentMatchers.anyList;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.when;
-
-/**
- * Created by abonnet on 10/14/16.
- */
-public class ApplicationsConfigurator {
-
- /**
- * Should take only Application and AppVersion classes in the sequence :
- * Application AppVersion+
- * (an application followed by one or more version)
- */
- public static void configureApplications(
- BaseWebSpringIT test,
- User user,
- List classes,
- Object... args) throws BusinessException {
- // parse the args to map the application to the versions
- Application currentApplication = null;
- Map> applicationVersions = new HashMap<>();
- for (Object currentArg : args) {
- if (currentArg instanceof Application) {
- currentApplication = (Application) currentArg;
- applicationVersions.put(currentApplication, new ArrayList<>());
- } else {
- applicationVersions.get(currentApplication).
- add(getVersion((AppVersion) currentArg, currentApplication));
- }
- }
- List classNames =
- classes.stream().map(AppClass::getName).collect(Collectors.toList());
- // verify the classes given are good
- Predicate isAppNotOK =
- app -> Collections.disjoint(app.getApplicationClasses(), classNames);
- if (applicationVersions.keySet().stream().anyMatch(isAppNotOK)) {
- throw new RuntimeException("misconfiguration of test class>app config");
- }
- // configure mocks
- ClassBusiness classBusiness = test.getClassBusiness();
- ApplicationBusiness applicationBusiness = test.getApplicationBusiness();
- // 1 return user classes
- when(classBusiness.getUserClasses(eq(user.getEmail()), eq(false)))
- .thenReturn(classes);
- when(classBusiness.getUserClassesName(
- eq(user.getEmail()), eq(false)))
- .thenReturn(classNames);
- // 2 return apps for the classes
- when(applicationBusiness.getApplications(anyList())).
- thenReturn(new ArrayList<>(applicationVersions.keySet()));
- // 3 return versions for each app
- for (Application app : applicationVersions.keySet()) {
- when(applicationBusiness.getVersions(eq(app.getName())))
- .thenReturn(applicationVersions.get(app));
- when(applicationBusiness.getApplication(eq(app.getName())))
- .thenReturn(app);
- }
- }
-
- public static String configureAnApplication(
- BaseWebSpringIT test,
- User user, Application app,
- AppVersion version,
- Integer... appParamsIndexes) throws BusinessException {
- WorkflowBusiness workflowBusiness = test.getWorkflowBusiness();
- when(workflowBusiness.getApplicationDescriptor(
- eq(user), eq(app.getName()), eq(version.getVersion())))
- .thenReturn(getDescriptor("desc test", appParamsIndexes));
- return app.getName() + "/" + version.getVersion();
- }
-}
diff --git a/vip-api/src/test/resources/TestHome/.vip/vip.conf b/vip-api/src/test/resources/TestHome/.vip/vip.conf
deleted file mode 100644
index e69de29bb..000000000
diff --git a/vip-api/src/test/resources/boutiques/test-boutiques.json b/vip-api/src/test/resources/boutiques/test-boutiques.json
new file mode 100644
index 000000000..e8fafc49f
--- /dev/null
+++ b/vip-api/src/test/resources/boutiques/test-boutiques.json
@@ -0,0 +1,68 @@
+{
+ "name": "testBoutiquesApp",
+ "tool-version": "v42",
+ "description": "Test app from axel. Must be similar to the gwendia test app",
+ "schema-version": "0.5",
+ "command-line": "echo [testFileInput] [testTextInput] [testOptionalTextInput] [testFlagInput]",
+ "author": "Axel ",
+ "container-image": {
+ "index": "docker://",
+ "image": "test-axel",
+ "type": "docker",
+ "container-opts": [
+ "-v /tmp:/tmp"
+ ]
+ },
+ "inputs": [
+ {
+ "id": "testFileInput",
+ "name": "Test file input",
+ "type": "File",
+ "description": "This is a test file input",
+ "value-key": "[testFileInput]"
+ },
+ {
+ "id": "testTextInput",
+ "name": "Test text input",
+ "type": "String",
+ "default-value": "test text value",
+ "description": "This is a test text input",
+ "value-key": "[testTextInput]"
+ },
+ {
+ "id": "testOptionalTextInput",
+ "name": "Test optional text input",
+ "type": "String",
+ "optional": true,
+ "description": "This is a optional test text input",
+ "value-key": "[testOptionalTextInput]"
+ },
+ {
+ "id": "testFlagInput",
+ "name": "Test flag input",
+ "type": "Flag",
+ "optional": true,
+ "default-value": "false",
+ "description": "This is a test flag input",
+ "command-line-flag": "--test-flag",
+ "value-key": "[testFlagInput]"
+ }
+ ],
+ "output-files": [
+ {
+ "id": "UNUSED",
+ "name": "Output",
+ "optional": false,
+ "description": "UNUSED",
+ "path-template": "UNUSED.tgz"
+ }
+ ], "error-codes": [
+ {
+ "description": "Crashed",
+ "code": 1
+ }
+ ],
+ "custom": {
+ "vip:plop": "plop"
+ }
+}
diff --git a/vip-api/src/test/resources/gwendia/basic-gwendia.gwendia b/vip-api/src/test/resources/gwendia/basic-gwendia.gwendia
new file mode 100644
index 000000000..b347235aa
--- /dev/null
+++ b/vip-api/src/test/resources/gwendia/basic-gwendia.gwendia
@@ -0,0 +1,72 @@
+
+
+ Test tool description. Must be similar to the boutiques one
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /*----------Beginning of Beanshell------------*/
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+String result = dir.toString();
+if ( result.startsWith("/") || result.startsWith("lfn:") ) {
+ DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy_HH:mm:ss");
+ result = result + "/" + (dateFormat.format(System.currentTimeMillis()));
+}
+/*------------End of Beanshell------------*/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/vip-api/src/test/resources/jsonObjects/execution1.json b/vip-api/src/test/resources/jsonObjects/execution1.json
index 3439e0d45..657cd07db 100644
--- a/vip-api/src/test/resources/jsonObjects/execution1.json
+++ b/vip-api/src/test/resources/jsonObjects/execution1.json
@@ -1,8 +1,8 @@
{
"name" : "Exec test 1",
- "pipelineIdentifier" : "application 1/4.2",
+ "pipelineIdentifier" : "test application/4.2",
"inputValues" : {
- "param 1" : "test text",
- "param 2" : "/path/test"
+ "testFileInput" : "/vip/Home/path/to/input.in",
+ "testTextInput" : "best test text value"
}
}
\ No newline at end of file
diff --git a/vip-api/src/test/resources/jsonObjects/user-credentials.json b/vip-api/src/test/resources/jsonObjects/user-credentials.json
index 7a5e602ec..bb04fd530 100644
--- a/vip-api/src/test/resources/jsonObjects/user-credentials.json
+++ b/vip-api/src/test/resources/jsonObjects/user-credentials.json
@@ -1,4 +1,4 @@
{
- "username":"baseuser1@test.tst",
+ "username":"test2@test.fr",
"password":"coucou"
}
\ No newline at end of file
diff --git a/vip-application/pom.xml b/vip-application/pom.xml
index 0f6a9ca52..99d66c8a7 100644
--- a/vip-application/pom.xml
+++ b/vip-application/pom.xml
@@ -105,7 +105,7 @@ knowledge of the CeCILL-B license and that you accept its terms.
org.jsoup
jsoup
- 1.7.2
+ 1.15.3
diff --git a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/client/bean/Application.java b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/client/bean/Application.java
index 5260abb36..3808641a7 100644
--- a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/client/bean/Application.java
+++ b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/client/bean/Application.java
@@ -34,6 +34,7 @@
import com.google.gwt.user.client.rpc.IsSerializable;
import org.opensaml.xml.encryption.Public;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -53,7 +54,7 @@ public Application() {
}
public Application(String name, String citation) {
- this(name, null, null, null, citation);
+ this(name, new ArrayList<>(), null, null, citation);
}
public Application(String name, List applicationClasses, String citation) {
diff --git a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/SpringApplicationConfig.java b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/SpringApplicationConfig.java
index 2c5f5d9d1..05d1609c5 100644
--- a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/SpringApplicationConfig.java
+++ b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/SpringApplicationConfig.java
@@ -1,5 +1,6 @@
package fr.insalyon.creatis.vip.application.server;
+import com.fasterxml.jackson.databind.ObjectMapper;
import fr.insalyon.creatis.moteur.plugins.workflowsdb.dao.*;
import fr.insalyon.creatis.vip.application.server.dao.SimulationStatsDAO;
import fr.insalyon.creatis.vip.application.server.dao.hibernate.SimulationStatsData;
@@ -7,6 +8,7 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
+import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
/**
* Spring special configuration for vip-application.
@@ -55,4 +57,5 @@ public InputDAO getInputDAO() throws WorkflowsDBDAOException {
public StatsDAO getStatsDAO() throws WorkflowsDBDAOException {
return workflowsDBDAOFactory().getStatsDAO();
}
+
}
diff --git a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/business/BoutiquesBusiness.java b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/business/BoutiquesBusiness.java
index af8baad1d..1da7addb0 100644
--- a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/business/BoutiquesBusiness.java
+++ b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/business/BoutiquesBusiness.java
@@ -31,7 +31,9 @@
*/
package fr.insalyon.creatis.vip.application.server.business;
+import com.fasterxml.jackson.databind.ObjectMapper;
import fr.insalyon.creatis.vip.application.client.bean.AppVersion;
+import fr.insalyon.creatis.vip.application.server.model.boutiques.BoutiquesDescriptor;
import fr.insalyon.creatis.vip.core.client.bean.User;
import fr.insalyon.creatis.vip.core.server.business.BusinessException;
import fr.insalyon.creatis.vip.core.server.business.Server;
@@ -45,6 +47,7 @@
import org.xml.sax.SAXException;
import java.io.*;
+import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
@@ -63,12 +66,15 @@ public class BoutiquesBusiness {
private Server server;
private DataManagerBusiness dataManagerBusiness;
private ApplicationBusiness applicationBusiness;
+ private ObjectMapper objectMapper;
@Autowired
- public BoutiquesBusiness(Server server, DataManagerBusiness dataManagerBusiness, ApplicationBusiness applicationBusiness) {
+ public BoutiquesBusiness(Server server, DataManagerBusiness dataManagerBusiness,
+ ApplicationBusiness applicationBusiness, ObjectMapper objectMapper) {
this.server = server;
this.dataManagerBusiness = dataManagerBusiness;
this.applicationBusiness = applicationBusiness;
+ this.objectMapper = objectMapper;
}
public String publishVersion(User user, String applicationName, String version)
@@ -133,6 +139,15 @@ public String getApplicationDescriptorString(
}
}
+ public BoutiquesDescriptor parseBoutiquesFile(File boutiquesFile) throws BusinessException {
+ try {
+ return objectMapper.readValue(boutiquesFile, BoutiquesDescriptor.class);
+ } catch (IOException e) {
+ logger.error("Error reading {} file for boutiques parsing", boutiquesFile, e);
+ throw new BusinessException("Error reading boutiques file", e);
+ }
+ }
+
private void saveDoiForVersion(
String doi, String applicationName, String applicationVersion)
throws BusinessException {
diff --git a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/business/WorkflowBusiness.java b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/business/WorkflowBusiness.java
index 55026d9b8..d192c4b28 100644
--- a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/business/WorkflowBusiness.java
+++ b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/business/WorkflowBusiness.java
@@ -41,6 +41,7 @@
import java.util.Map;
import java.util.Random;
+import fr.insalyon.creatis.vip.application.server.model.boutiques.BoutiquesDescriptor;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/dao/mysql/ApplicationData.java b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/dao/mysql/ApplicationData.java
index ba8fb761a..0c4f0d560 100644
--- a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/dao/mysql/ApplicationData.java
+++ b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/dao/mysql/ApplicationData.java
@@ -624,19 +624,19 @@ public AppVersion getVersion(String applicationName, String applicationVersion)
ps.setString(2, applicationVersion);
ResultSet rs = ps.executeQuery();
- rs.next();
-
- AppVersion version = new AppVersion(rs.getString("application"),
- rs.getString("version"),
- rs.getString("lfn"),
- rs.getString("json_lfn"),
- rs.getString("doi"),
- rs.getBoolean("visible"),
- rs.getBoolean("useBoutiquesForm"));
- ps.close();
-
- return version;
+ if (rs.first()) {
+ AppVersion version = new AppVersion(rs.getString("application"),
+ rs.getString("version"),
+ rs.getString("lfn"),
+ rs.getString("json_lfn"),
+ rs.getString("doi"),
+ rs.getBoolean("visible"),
+ rs.getBoolean("useBoutiquesForm"));
+ ps.close();
+ return version;
+ }
+ return null;
} catch (SQLException ex) {
logger.error("Error getting versions for {}/{}",
applicationName, applicationVersion, ex);
diff --git a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/Assertions.java b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/Assertions.java
new file mode 100644
index 000000000..c896e08e7
--- /dev/null
+++ b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/Assertions.java
@@ -0,0 +1,75 @@
+
+package fr.insalyon.creatis.vip.application.server.model.boutiques;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.Generated;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyDescription;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "exit-code",
+ "output-files"
+})
+@Generated("jsonschema2pojo")
+public class Assertions {
+
+ /**
+ * Expected code returned by the program.
+ *
+ */
+ @JsonProperty("exit-code")
+ @JsonPropertyDescription("Expected code returned by the program.")
+ private Integer exitCode;
+ @JsonProperty("output-files")
+ private List testOutputFiles = new ArrayList();
+ @JsonIgnore
+ private Map additionalProperties = new LinkedHashMap();
+
+ /**
+ * Expected code returned by the program.
+ *
+ */
+ @JsonProperty("exit-code")
+ public Integer getExitCode() {
+ return exitCode;
+ }
+
+ /**
+ * Expected code returned by the program.
+ *
+ */
+ @JsonProperty("exit-code")
+ public void setExitCode(Integer exitCode) {
+ this.exitCode = exitCode;
+ }
+
+ @JsonProperty("output-files")
+ public List getOutputFiles() {
+ return testOutputFiles;
+ }
+
+ @JsonProperty("output-files")
+ public void setOutputFiles(List testOutputFiles) {
+ this.testOutputFiles = testOutputFiles;
+ }
+
+ @JsonAnyGetter
+ public Map getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+}
diff --git a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/BoutiquesDescriptor.java b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/BoutiquesDescriptor.java
new file mode 100644
index 000000000..fd20ed071
--- /dev/null
+++ b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/BoutiquesDescriptor.java
@@ -0,0 +1,645 @@
+
+package fr.insalyon.creatis.vip.application.server.model.boutiques;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.Generated;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyDescription;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.annotation.JsonValue;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+
+
+/**
+ * Tool
+ *
+ *
+ *
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "name",
+ "tool-version",
+ "description",
+ "deprecated-by-doi",
+ "author",
+ "url",
+ "descriptor-url",
+ "doi",
+ "shell",
+ "tool-doi",
+ "command-line",
+ "container-image",
+ "schema-version",
+ "environment-variables",
+ "groups",
+ "inputs",
+ "tests",
+ "online-platform-urls",
+ "output-files",
+ "invocation-schema",
+ "suggested-resources",
+ "tags",
+ "error-codes",
+ "custom"
+})
+@Generated("jsonschema2pojo")
+public class BoutiquesDescriptor {
+
+ /**
+ * Tool name.
+ * (Required)
+ *
+ */
+ @JsonProperty("name")
+ @JsonPropertyDescription("Tool name.")
+ private String name;
+ /**
+ * Tool version.
+ * (Required)
+ *
+ */
+ @JsonProperty("tool-version")
+ @JsonPropertyDescription("Tool version.")
+ private String toolVersion;
+ /**
+ * Tool description.
+ * (Required)
+ *
+ */
+ @JsonProperty("description")
+ @JsonPropertyDescription("Tool description.")
+ private String description;
+ /**
+ * doi of the tool that deprecates the current one. May be set to 'true' if the current tool is deprecated but no specific tool deprecates it.
+ *
+ */
+ @JsonProperty("deprecated-by-doi")
+ @JsonPropertyDescription("doi of the tool that deprecates the current one. May be set to 'true' if the current tool is deprecated but no specific tool deprecates it.")
+ private String deprecatedByDoi;
+ /**
+ * Tool author name(s).
+ *
+ */
+ @JsonProperty("author")
+ @JsonPropertyDescription("Tool author name(s).")
+ private String author;
+ /**
+ * Tool URL.
+ *
+ */
+ @JsonProperty("url")
+ @JsonPropertyDescription("Tool URL.")
+ private String url;
+ /**
+ * Link to the descriptor itself (e.g. the GitHub repo where it is hosted).
+ *
+ */
+ @JsonProperty("descriptor-url")
+ @JsonPropertyDescription("Link to the descriptor itself (e.g. the GitHub repo where it is hosted).")
+ private String descriptorUrl;
+ /**
+ * DOI of the descriptor (not of the tool itself).
+ *
+ */
+ @JsonProperty("doi")
+ @JsonPropertyDescription("DOI of the descriptor (not of the tool itself).")
+ private String doi;
+ /**
+ * Absolute path of the shell interpreter to use in the container (defaults to /bin/sh).
+ *
+ */
+ @JsonProperty("shell")
+ @JsonPropertyDescription("Absolute path of the shell interpreter to use in the container (defaults to /bin/sh).")
+ private String shell;
+ /**
+ * DOI of the tool (not of the descriptor).
+ *
+ */
+ @JsonProperty("tool-doi")
+ @JsonPropertyDescription("DOI of the tool (not of the descriptor).")
+ private String toolDoi;
+ /**
+ * A string that describes the tool command line, where input and output values are identified by "keys". At runtime, command-line keys are substituted with flags and values.
+ * (Required)
+ *
+ */
+ @JsonProperty("command-line")
+ @JsonPropertyDescription("A string that describes the tool command line, where input and output values are identified by \"keys\". At runtime, command-line keys are substituted with flags and values.")
+ private String commandLine;
+ @JsonProperty("container-image")
+ private ContainerImage containerImage;
+ /**
+ * Version of the schema used.
+ * (Required)
+ *
+ */
+ @JsonProperty("schema-version")
+ @JsonPropertyDescription("Version of the schema used.")
+ private BoutiquesDescriptor.SchemaVersion schemaVersion;
+ /**
+ * An array of key-value pairs specifying environment variable names and their values to be used in the execution environment.
+ *
+ */
+ @JsonProperty("environment-variables")
+ @JsonDeserialize(as = java.util.LinkedHashSet.class)
+ @JsonPropertyDescription("An array of key-value pairs specifying environment variable names and their values to be used in the execution environment.")
+ private Set environmentVariables = new LinkedHashSet();
+ /**
+ * Sets of identifiers of inputs, each specifying an input group.
+ *
+ */
+ @JsonProperty("groups")
+ @JsonDeserialize(as = java.util.LinkedHashSet.class)
+ @JsonPropertyDescription("Sets of identifiers of inputs, each specifying an input group.")
+ private Set groups = new LinkedHashSet();
+ /**
+ *
+ * (Required)
+ *
+ */
+ @JsonProperty("inputs")
+ @JsonDeserialize(as = java.util.LinkedHashSet.class)
+ private Set inputs = new LinkedHashSet();
+ @JsonProperty("tests")
+ private List tests = new ArrayList();
+ /**
+ * Online platform URLs from which the tool can be executed.
+ *
+ */
+ @JsonProperty("online-platform-urls")
+ @JsonPropertyDescription("Online platform URLs from which the tool can be executed.")
+ private List onlinePlatformUrls = new ArrayList();
+ @JsonProperty("output-files")
+ @JsonDeserialize(as = java.util.LinkedHashSet.class)
+ private Set outputFiles = new LinkedHashSet();
+ @JsonProperty("invocation-schema")
+ private InvocationSchema invocationSchema;
+ @JsonProperty("suggested-resources")
+ private SuggestedResources suggestedResources;
+ /**
+ * A set of key-value pairs specifying tags describing the pipeline. The tag names are open, they might be more constrained in the future.
+ *
+ */
+ @JsonProperty("tags")
+ @JsonPropertyDescription("A set of key-value pairs specifying tags describing the pipeline. The tag names are open, they might be more constrained in the future.")
+ private Tags tags;
+ /**
+ * An array of key-value pairs specifying exit codes and their description. Can be used for tools to specify the meaning of particular exit codes. Exit code 0 is assumed to indicate a successful execution.
+ *
+ */
+ @JsonProperty("error-codes")
+ @JsonDeserialize(as = java.util.LinkedHashSet.class)
+ @JsonPropertyDescription("An array of key-value pairs specifying exit codes and their description. Can be used for tools to specify the meaning of particular exit codes. Exit code 0 is assumed to indicate a successful execution.")
+ private Set errorCodes = new LinkedHashSet();
+ @JsonProperty("custom")
+ private Custom custom;
+
+ /**
+ * Tool name.
+ * (Required)
+ *
+ */
+ @JsonProperty("name")
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Tool name.
+ * (Required)
+ *
+ */
+ @JsonProperty("name")
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Tool version.
+ * (Required)
+ *
+ */
+ @JsonProperty("tool-version")
+ public String getToolVersion() {
+ return toolVersion;
+ }
+
+ /**
+ * Tool version.
+ * (Required)
+ *
+ */
+ @JsonProperty("tool-version")
+ public void setToolVersion(String toolVersion) {
+ this.toolVersion = toolVersion;
+ }
+
+ /**
+ * Tool description.
+ * (Required)
+ *
+ */
+ @JsonProperty("description")
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Tool description.
+ * (Required)
+ *
+ */
+ @JsonProperty("description")
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ /**
+ * doi of the tool that deprecates the current one. May be set to 'true' if the current tool is deprecated but no specific tool deprecates it.
+ *
+ */
+ @JsonProperty("deprecated-by-doi")
+ public String getDeprecatedByDoi() {
+ return deprecatedByDoi;
+ }
+
+ /**
+ * doi of the tool that deprecates the current one. May be set to 'true' if the current tool is deprecated but no specific tool deprecates it.
+ *
+ */
+ @JsonProperty("deprecated-by-doi")
+ public void setDeprecatedByDoi(String deprecatedByDoi) {
+ this.deprecatedByDoi = deprecatedByDoi;
+ }
+
+ /**
+ * Tool author name(s).
+ *
+ */
+ @JsonProperty("author")
+ public String getAuthor() {
+ return author;
+ }
+
+ /**
+ * Tool author name(s).
+ *
+ */
+ @JsonProperty("author")
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+
+ /**
+ * Tool URL.
+ *
+ */
+ @JsonProperty("url")
+ public String getUrl() {
+ return url;
+ }
+
+ /**
+ * Tool URL.
+ *
+ */
+ @JsonProperty("url")
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ /**
+ * Link to the descriptor itself (e.g. the GitHub repo where it is hosted).
+ *
+ */
+ @JsonProperty("descriptor-url")
+ public String getDescriptorUrl() {
+ return descriptorUrl;
+ }
+
+ /**
+ * Link to the descriptor itself (e.g. the GitHub repo where it is hosted).
+ *
+ */
+ @JsonProperty("descriptor-url")
+ public void setDescriptorUrl(String descriptorUrl) {
+ this.descriptorUrl = descriptorUrl;
+ }
+
+ /**
+ * DOI of the descriptor (not of the tool itself).
+ *
+ */
+ @JsonProperty("doi")
+ public String getDoi() {
+ return doi;
+ }
+
+ /**
+ * DOI of the descriptor (not of the tool itself).
+ *
+ */
+ @JsonProperty("doi")
+ public void setDoi(String doi) {
+ this.doi = doi;
+ }
+
+ /**
+ * Absolute path of the shell interpreter to use in the container (defaults to /bin/sh).
+ *
+ */
+ @JsonProperty("shell")
+ public String getShell() {
+ return shell;
+ }
+
+ /**
+ * Absolute path of the shell interpreter to use in the container (defaults to /bin/sh).
+ *
+ */
+ @JsonProperty("shell")
+ public void setShell(String shell) {
+ this.shell = shell;
+ }
+
+ /**
+ * DOI of the tool (not of the descriptor).
+ *
+ */
+ @JsonProperty("tool-doi")
+ public String getToolDoi() {
+ return toolDoi;
+ }
+
+ /**
+ * DOI of the tool (not of the descriptor).
+ *
+ */
+ @JsonProperty("tool-doi")
+ public void setToolDoi(String toolDoi) {
+ this.toolDoi = toolDoi;
+ }
+
+ /**
+ * A string that describes the tool command line, where input and output values are identified by "keys". At runtime, command-line keys are substituted with flags and values.
+ * (Required)
+ *
+ */
+ @JsonProperty("command-line")
+ public String getCommandLine() {
+ return commandLine;
+ }
+
+ /**
+ * A string that describes the tool command line, where input and output values are identified by "keys". At runtime, command-line keys are substituted with flags and values.
+ * (Required)
+ *
+ */
+ @JsonProperty("command-line")
+ public void setCommandLine(String commandLine) {
+ this.commandLine = commandLine;
+ }
+
+ @JsonProperty("container-image")
+ public ContainerImage getContainerImage() {
+ return containerImage;
+ }
+
+ @JsonProperty("container-image")
+ public void setContainerImage(ContainerImage containerImage) {
+ this.containerImage = containerImage;
+ }
+
+ /**
+ * Version of the schema used.
+ * (Required)
+ *
+ */
+ @JsonProperty("schema-version")
+ public BoutiquesDescriptor.SchemaVersion getSchemaVersion() {
+ return schemaVersion;
+ }
+
+ /**
+ * Version of the schema used.
+ * (Required)
+ *
+ */
+ @JsonProperty("schema-version")
+ public void setSchemaVersion(BoutiquesDescriptor.SchemaVersion schemaVersion) {
+ this.schemaVersion = schemaVersion;
+ }
+
+ /**
+ * An array of key-value pairs specifying environment variable names and their values to be used in the execution environment.
+ *
+ */
+ @JsonProperty("environment-variables")
+ public Set getEnvironmentVariables() {
+ return environmentVariables;
+ }
+
+ /**
+ * An array of key-value pairs specifying environment variable names and their values to be used in the execution environment.
+ *
+ */
+ @JsonProperty("environment-variables")
+ public void setEnvironmentVariables(Set environmentVariables) {
+ this.environmentVariables = environmentVariables;
+ }
+
+ /**
+ * Sets of identifiers of inputs, each specifying an input group.
+ *
+ */
+ @JsonProperty("groups")
+ public Set getGroups() {
+ return groups;
+ }
+
+ /**
+ * Sets of identifiers of inputs, each specifying an input group.
+ *
+ */
+ @JsonProperty("groups")
+ public void setGroups(Set groups) {
+ this.groups = groups;
+ }
+
+ /**
+ *
+ * (Required)
+ *
+ */
+ @JsonProperty("inputs")
+ public Set getInputs() {
+ return inputs;
+ }
+
+ /**
+ *
+ * (Required)
+ *
+ */
+ @JsonProperty("inputs")
+ public void setInputs(Set inputs) {
+ this.inputs = inputs;
+ }
+
+ @JsonProperty("tests")
+ public List getTests() {
+ return tests;
+ }
+
+ @JsonProperty("tests")
+ public void setTests(List tests) {
+ this.tests = tests;
+ }
+
+ /**
+ * Online platform URLs from which the tool can be executed.
+ *
+ */
+ @JsonProperty("online-platform-urls")
+ public List getOnlinePlatformUrls() {
+ return onlinePlatformUrls;
+ }
+
+ /**
+ * Online platform URLs from which the tool can be executed.
+ *
+ */
+ @JsonProperty("online-platform-urls")
+ public void setOnlinePlatformUrls(List onlinePlatformUrls) {
+ this.onlinePlatformUrls = onlinePlatformUrls;
+ }
+
+ @JsonProperty("output-files")
+ public Set getOutputFiles() {
+ return outputFiles;
+ }
+
+ @JsonProperty("output-files")
+ public void setOutputFiles(Set outputFiles) {
+ this.outputFiles = outputFiles;
+ }
+
+ @JsonProperty("invocation-schema")
+ public InvocationSchema getInvocationSchema() {
+ return invocationSchema;
+ }
+
+ @JsonProperty("invocation-schema")
+ public void setInvocationSchema(InvocationSchema invocationSchema) {
+ this.invocationSchema = invocationSchema;
+ }
+
+ @JsonProperty("suggested-resources")
+ public SuggestedResources getSuggestedResources() {
+ return suggestedResources;
+ }
+
+ @JsonProperty("suggested-resources")
+ public void setSuggestedResources(SuggestedResources suggestedResources) {
+ this.suggestedResources = suggestedResources;
+ }
+
+ /**
+ * A set of key-value pairs specifying tags describing the pipeline. The tag names are open, they might be more constrained in the future.
+ *
+ */
+ @JsonProperty("tags")
+ public Tags getTags() {
+ return tags;
+ }
+
+ /**
+ * A set of key-value pairs specifying tags describing the pipeline. The tag names are open, they might be more constrained in the future.
+ *
+ */
+ @JsonProperty("tags")
+ public void setTags(Tags tags) {
+ this.tags = tags;
+ }
+
+ /**
+ * An array of key-value pairs specifying exit codes and their description. Can be used for tools to specify the meaning of particular exit codes. Exit code 0 is assumed to indicate a successful execution.
+ *
+ */
+ @JsonProperty("error-codes")
+ public Set getErrorCodes() {
+ return errorCodes;
+ }
+
+ /**
+ * An array of key-value pairs specifying exit codes and their description. Can be used for tools to specify the meaning of particular exit codes. Exit code 0 is assumed to indicate a successful execution.
+ *
+ */
+ @JsonProperty("error-codes")
+ public void setErrorCodes(Set errorCodes) {
+ this.errorCodes = errorCodes;
+ }
+
+ @JsonProperty("custom")
+ public Custom getCustom() {
+ return custom;
+ }
+
+ @JsonProperty("custom")
+ public void setCustom(Custom custom) {
+ this.custom = custom;
+ }
+
+
+ /**
+ * Version of the schema used.
+ *
+ */
+ @Generated("jsonschema2pojo")
+ public enum SchemaVersion {
+
+ _0_5("0.5");
+ private final String value;
+ private final static Map CONSTANTS = new HashMap();
+
+ static {
+ for (BoutiquesDescriptor.SchemaVersion c: values()) {
+ CONSTANTS.put(c.value, c);
+ }
+ }
+
+ SchemaVersion(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return this.value;
+ }
+
+ @JsonValue
+ public String value() {
+ return this.value;
+ }
+
+ @JsonCreator
+ public static BoutiquesDescriptor.SchemaVersion fromValue(String value) {
+ BoutiquesDescriptor.SchemaVersion constant = CONSTANTS.get(value);
+ if (constant == null) {
+ throw new IllegalArgumentException(value);
+ } else {
+ return constant;
+ }
+ }
+
+ }
+
+}
diff --git a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/ConditionalPathTemplate.java b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/ConditionalPathTemplate.java
new file mode 100644
index 000000000..e0c99b130
--- /dev/null
+++ b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/ConditionalPathTemplate.java
@@ -0,0 +1,46 @@
+
+package fr.insalyon.creatis.vip.application.server.model.boutiques;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import javax.annotation.Generated;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "propertyNames"
+})
+@Generated("jsonschema2pojo")
+public class ConditionalPathTemplate {
+
+ @JsonProperty("propertyNames")
+ private Object propertyNames;
+ @JsonIgnore
+ private Map additionalProperties = new LinkedHashMap();
+
+ @JsonProperty("propertyNames")
+ public Object getPropertyNames() {
+ return propertyNames;
+ }
+
+ @JsonProperty("propertyNames")
+ public void setPropertyNames(Object propertyNames) {
+ this.propertyNames = propertyNames;
+ }
+
+ @JsonAnyGetter
+ public Map getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+}
diff --git a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/ContainerImage.java b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/ContainerImage.java
new file mode 100644
index 000000000..3fb20917e
--- /dev/null
+++ b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/ContainerImage.java
@@ -0,0 +1,267 @@
+
+package fr.insalyon.creatis.vip.application.server.model.boutiques;
+
+import java.util.*;
+import javax.annotation.Generated;
+
+import com.fasterxml.jackson.annotation.*;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "type",
+ "image",
+ "entrypoint",
+ "index",
+ "container-opts",
+ "url",
+ "working-directory",
+ "container-hash"
+})
+@Generated("jsonschema2pojo")
+public class ContainerImage {
+
+ /**
+ *
+ * (Required)
+ *
+ */
+ @JsonProperty("type")
+ private ContainerImage.Type type;
+ /**
+ * Name of an image where the tool is installed and configured. Example: bids/mriqc.
+ *
+ */
+ @JsonProperty("image")
+ @JsonPropertyDescription("Name of an image where the tool is installed and configured. Example: bids/mriqc.")
+ private String image;
+ /**
+ * Flag indicating whether or not the container uses an entrypoint.
+ *
+ */
+ @JsonProperty("entrypoint")
+ @JsonPropertyDescription("Flag indicating whether or not the container uses an entrypoint.")
+ private Boolean entrypoint;
+ /**
+ * Optional index where the image is available, if not the standard location. Example: docker.io
+ *
+ */
+ @JsonProperty("index")
+ @JsonPropertyDescription("Optional index where the image is available, if not the standard location. Example: docker.io")
+ private String index;
+ /**
+ * Container-level arguments for the application. Example: --privileged
+ *
+ */
+ @JsonProperty("container-opts")
+ @JsonPropertyDescription("Container-level arguments for the application. Example: --privileged")
+ private List containerOpts = new ArrayList();
+ /**
+ * URL where the image is available.
+ *
+ */
+ @JsonProperty("url")
+ @JsonPropertyDescription("URL where the image is available.")
+ private String url;
+ /**
+ * Location from which this task must be launched within the container.
+ *
+ */
+ @JsonProperty("working-directory")
+ @JsonPropertyDescription("Location from which this task must be launched within the container.")
+ private String workingDirectory;
+ /**
+ * Hash for the given container.
+ *
+ */
+ @JsonProperty("container-hash")
+ @JsonPropertyDescription("Hash for the given container.")
+ private String containerHash;
+
+ /**
+ *
+ * (Required)
+ *
+ */
+ @JsonProperty("type")
+ public ContainerImage.Type getType() {
+ return type;
+ }
+
+ /**
+ *
+ * (Required)
+ *
+ */
+ @JsonProperty("type")
+ public void setType(ContainerImage.Type type) {
+ this.type = type;
+ }
+
+ /**
+ * Name of an image where the tool is installed and configured. Example: bids/mriqc.
+ *
+ */
+ @JsonProperty("image")
+ public String getImage() {
+ return image;
+ }
+
+ /**
+ * Name of an image where the tool is installed and configured. Example: bids/mriqc.
+ *
+ */
+ @JsonProperty("image")
+ public void setImage(String image) {
+ this.image = image;
+ }
+
+ /**
+ * Flag indicating whether or not the container uses an entrypoint.
+ *
+ */
+ @JsonProperty("entrypoint")
+ public Boolean getEntrypoint() {
+ return entrypoint;
+ }
+
+ /**
+ * Flag indicating whether or not the container uses an entrypoint.
+ *
+ */
+ @JsonProperty("entrypoint")
+ public void setEntrypoint(Boolean entrypoint) {
+ this.entrypoint = entrypoint;
+ }
+
+ /**
+ * Optional index where the image is available, if not the standard location. Example: docker.io
+ *
+ */
+ @JsonProperty("index")
+ public String getIndex() {
+ return index;
+ }
+
+ /**
+ * Optional index where the image is available, if not the standard location. Example: docker.io
+ *
+ */
+ @JsonProperty("index")
+ public void setIndex(String index) {
+ this.index = index;
+ }
+
+ /**
+ * Container-level arguments for the application. Example: --privileged
+ *
+ */
+ @JsonProperty("container-opts")
+ public List getContainerOpts() {
+ return containerOpts;
+ }
+
+ /**
+ * Container-level arguments for the application. Example: --privileged
+ *
+ */
+ @JsonProperty("container-opts")
+ public void setContainerOpts(List containerOpts) {
+ this.containerOpts = containerOpts;
+ }
+
+ /**
+ * URL where the image is available.
+ *
+ */
+ @JsonProperty("url")
+ public String getUrl() {
+ return url;
+ }
+
+ /**
+ * URL where the image is available.
+ *
+ */
+ @JsonProperty("url")
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ /**
+ * Location from which this task must be launched within the container.
+ *
+ */
+ @JsonProperty("working-directory")
+ public String getWorkingDirectory() {
+ return workingDirectory;
+ }
+
+ /**
+ * Location from which this task must be launched within the container.
+ *
+ */
+ @JsonProperty("working-directory")
+ public void setWorkingDirectory(String workingDirectory) {
+ this.workingDirectory = workingDirectory;
+ }
+
+ /**
+ * Hash for the given container.
+ *
+ */
+ @JsonProperty("container-hash")
+ public String getContainerHash() {
+ return containerHash;
+ }
+
+ /**
+ * Hash for the given container.
+ *
+ */
+ @JsonProperty("container-hash")
+ public void setContainerHash(String containerHash) {
+ this.containerHash = containerHash;
+ }
+
+ @Generated("jsonschema2pojo")
+ public enum Type {
+
+ DOCKER("docker"),
+ SINGULARITY("singularity"),
+ ROOTFS("rootfs");
+ private final String value;
+ private final static Map CONSTANTS = new HashMap();
+
+ static {
+ for (ContainerImage.Type c: values()) {
+ CONSTANTS.put(c.value, c);
+ }
+ }
+
+ Type(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return this.value;
+ }
+
+ @JsonValue
+ public String value() {
+ return this.value;
+ }
+
+ @JsonCreator
+ public static ContainerImage.Type fromValue(String value) {
+ ContainerImage.Type constant = CONSTANTS.get(value);
+ if (constant == null) {
+ throw new IllegalArgumentException(value);
+ } else {
+ return constant;
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/Custom.java b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/Custom.java
new file mode 100644
index 000000000..f0a998f3f
--- /dev/null
+++ b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/Custom.java
@@ -0,0 +1,33 @@
+
+package fr.insalyon.creatis.vip.application.server.model.boutiques;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import javax.annotation.Generated;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+
+})
+@Generated("jsonschema2pojo")
+public class Custom {
+
+ @JsonIgnore
+ private Map additionalProperties = new LinkedHashMap();
+
+ @JsonAnyGetter
+ public Map getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+}
diff --git a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/EnvironmentVariable.java b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/EnvironmentVariable.java
new file mode 100644
index 000000000..d8a0eabb2
--- /dev/null
+++ b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/EnvironmentVariable.java
@@ -0,0 +1,101 @@
+
+package fr.insalyon.creatis.vip.application.server.model.boutiques;
+
+import javax.annotation.Generated;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyDescription;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "name",
+ "value",
+ "description"
+})
+@Generated("jsonschema2pojo")
+public class EnvironmentVariable {
+
+ /**
+ * The environment variable name (identifier) containing only alphanumeric characters and underscores. Example: "PROGRAM_PATH".
+ * (Required)
+ *
+ */
+ @JsonProperty("name")
+ @JsonPropertyDescription("The environment variable name (identifier) containing only alphanumeric characters and underscores. Example: \"PROGRAM_PATH\".")
+ private String name;
+ /**
+ * The value of the environment variable.
+ * (Required)
+ *
+ */
+ @JsonProperty("value")
+ @JsonPropertyDescription("The value of the environment variable.")
+ private String value;
+ /**
+ * Description of the environment variable.
+ *
+ */
+ @JsonProperty("description")
+ @JsonPropertyDescription("Description of the environment variable.")
+ private String description;
+
+ /**
+ * The environment variable name (identifier) containing only alphanumeric characters and underscores. Example: "PROGRAM_PATH".
+ * (Required)
+ *
+ */
+ @JsonProperty("name")
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * The environment variable name (identifier) containing only alphanumeric characters and underscores. Example: "PROGRAM_PATH".
+ * (Required)
+ *
+ */
+ @JsonProperty("name")
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * The value of the environment variable.
+ * (Required)
+ *
+ */
+ @JsonProperty("value")
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * The value of the environment variable.
+ * (Required)
+ *
+ */
+ @JsonProperty("value")
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Description of the environment variable.
+ *
+ */
+ @JsonProperty("description")
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Description of the environment variable.
+ *
+ */
+ @JsonProperty("description")
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+}
diff --git a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/ErrorCode.java b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/ErrorCode.java
new file mode 100644
index 000000000..8929b1608
--- /dev/null
+++ b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/ErrorCode.java
@@ -0,0 +1,75 @@
+
+package fr.insalyon.creatis.vip.application.server.model.boutiques;
+
+import javax.annotation.Generated;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyDescription;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "code",
+ "description"
+})
+@Generated("jsonschema2pojo")
+public class ErrorCode {
+
+ /**
+ * Value of the exit code
+ * (Required)
+ *
+ */
+ @JsonProperty("code")
+ @JsonPropertyDescription("Value of the exit code")
+ private Integer code;
+ /**
+ * Description of the error code.
+ * (Required)
+ *
+ */
+ @JsonProperty("description")
+ @JsonPropertyDescription("Description of the error code.")
+ private String description;
+
+ /**
+ * Value of the exit code
+ * (Required)
+ *
+ */
+ @JsonProperty("code")
+ public Integer getCode() {
+ return code;
+ }
+
+ /**
+ * Value of the exit code
+ * (Required)
+ *
+ */
+ @JsonProperty("code")
+ public void setCode(Integer code) {
+ this.code = code;
+ }
+
+ /**
+ * Description of the error code.
+ * (Required)
+ *
+ */
+ @JsonProperty("description")
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Description of the error code.
+ * (Required)
+ *
+ */
+ @JsonProperty("description")
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+}
diff --git a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/Group.java b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/Group.java
new file mode 100644
index 000000000..064badeb4
--- /dev/null
+++ b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/Group.java
@@ -0,0 +1,210 @@
+
+package fr.insalyon.creatis.vip.application.server.model.boutiques;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.Generated;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyDescription;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "id",
+ "name",
+ "description",
+ "members",
+ "mutually-exclusive",
+ "one-is-required",
+ "all-or-none"
+})
+@Generated("jsonschema2pojo")
+public class Group {
+
+ /**
+ * A short, unique, informative identifier containing only alphanumeric characters and underscores. Typically used to generate variable names. Example: "outfile_group".
+ * (Required)
+ *
+ */
+ @JsonProperty("id")
+ @JsonPropertyDescription("A short, unique, informative identifier containing only alphanumeric characters and underscores. Typically used to generate variable names. Example: \"outfile_group\".")
+ private String id;
+ /**
+ * A human-readable name for the input group.
+ * (Required)
+ *
+ */
+ @JsonProperty("name")
+ @JsonPropertyDescription("A human-readable name for the input group.")
+ private String name;
+ /**
+ * Description of the input group.
+ *
+ */
+ @JsonProperty("description")
+ @JsonPropertyDescription("Description of the input group.")
+ private String description;
+ /**
+ * IDs of the inputs belonging to this group.
+ * (Required)
+ *
+ */
+ @JsonProperty("members")
+ @JsonPropertyDescription("IDs of the inputs belonging to this group.")
+ private List members = new ArrayList();
+ /**
+ * True if only one input in the group may be active at runtime.
+ *
+ */
+ @JsonProperty("mutually-exclusive")
+ @JsonPropertyDescription("True if only one input in the group may be active at runtime.")
+ private Boolean mutuallyExclusive;
+ /**
+ * True if at least one of the inputs in the group must be active at runtime.
+ *
+ */
+ @JsonProperty("one-is-required")
+ @JsonPropertyDescription("True if at least one of the inputs in the group must be active at runtime.")
+ private Boolean oneIsRequired;
+ /**
+ * True if members of the group need to be toggled together
+ *
+ */
+ @JsonProperty("all-or-none")
+ @JsonPropertyDescription("True if members of the group need to be toggled together")
+ private Boolean allOrNone;
+
+ /**
+ * A short, unique, informative identifier containing only alphanumeric characters and underscores. Typically used to generate variable names. Example: "outfile_group".
+ * (Required)
+ *
+ */
+ @JsonProperty("id")
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * A short, unique, informative identifier containing only alphanumeric characters and underscores. Typically used to generate variable names. Example: "outfile_group".
+ * (Required)
+ *
+ */
+ @JsonProperty("id")
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * A human-readable name for the input group.
+ * (Required)
+ *
+ */
+ @JsonProperty("name")
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * A human-readable name for the input group.
+ * (Required)
+ *
+ */
+ @JsonProperty("name")
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Description of the input group.
+ *
+ */
+ @JsonProperty("description")
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Description of the input group.
+ *
+ */
+ @JsonProperty("description")
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ /**
+ * IDs of the inputs belonging to this group.
+ * (Required)
+ *
+ */
+ @JsonProperty("members")
+ public List getMembers() {
+ return members;
+ }
+
+ /**
+ * IDs of the inputs belonging to this group.
+ * (Required)
+ *
+ */
+ @JsonProperty("members")
+ public void setMembers(List members) {
+ this.members = members;
+ }
+
+ /**
+ * True if only one input in the group may be active at runtime.
+ *
+ */
+ @JsonProperty("mutually-exclusive")
+ public Boolean getMutuallyExclusive() {
+ return mutuallyExclusive;
+ }
+
+ /**
+ * True if only one input in the group may be active at runtime.
+ *
+ */
+ @JsonProperty("mutually-exclusive")
+ public void setMutuallyExclusive(Boolean mutuallyExclusive) {
+ this.mutuallyExclusive = mutuallyExclusive;
+ }
+
+ /**
+ * True if at least one of the inputs in the group must be active at runtime.
+ *
+ */
+ @JsonProperty("one-is-required")
+ public Boolean getOneIsRequired() {
+ return oneIsRequired;
+ }
+
+ /**
+ * True if at least one of the inputs in the group must be active at runtime.
+ *
+ */
+ @JsonProperty("one-is-required")
+ public void setOneIsRequired(Boolean oneIsRequired) {
+ this.oneIsRequired = oneIsRequired;
+ }
+
+ /**
+ * True if members of the group need to be toggled together
+ *
+ */
+ @JsonProperty("all-or-none")
+ public Boolean getAllOrNone() {
+ return allOrNone;
+ }
+
+ /**
+ * True if members of the group need to be toggled together
+ *
+ */
+ @JsonProperty("all-or-none")
+ public void setAllOrNone(Boolean allOrNone) {
+ this.allOrNone = allOrNone;
+ }
+
+}
diff --git a/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/Input.java b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/Input.java
new file mode 100644
index 000000000..8dc8f878b
--- /dev/null
+++ b/vip-application/src/main/java/fr/insalyon/creatis/vip/application/server/model/boutiques/Input.java
@@ -0,0 +1,703 @@
+
+package fr.insalyon.creatis.vip.application.server.model.boutiques;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.Generated;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyDescription;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "id",
+ "name",
+ "type",
+ "description",
+ "value-key",
+ "list",
+ "list-separator",
+ "optional",
+ "command-line-flag",
+ "requires-inputs",
+ "disables-inputs",
+ "command-line-flag-separator",
+ "default-value",
+ "value-choices",
+ "value-requires",
+ "value-disables",
+ "integer",
+ "minimum",
+ "maximum",
+ "exclusive-minimum",
+ "exclusive-maximum",
+ "min-list-entries",
+ "max-list-entries",
+ "uses-absolute-path"
+})
+@Generated("jsonschema2pojo")
+public class Input {
+
+ /**
+ * A short, unique, informative identifier containing only alphanumeric characters and underscores. Typically used to generate variable names. Example: "data_file".
+ * (Required)
+ *
+ */
+ @JsonProperty("id")
+ @JsonPropertyDescription("A short, unique, informative identifier containing only alphanumeric characters and underscores. Typically used to generate variable names. Example: \"data_file\".")
+ private String id;
+ /**
+ * A human-readable input name. Example: 'Data file'.
+ * (Required)
+ *
+ */
+ @JsonProperty("name")
+ @JsonPropertyDescription("A human-readable input name. Example: 'Data file'.")
+ private String name;
+ /**
+ * Input type.
+ * (Required)
+ *
+ */
+ @JsonProperty("type")
+ @JsonPropertyDescription("Input type.")
+ private Input.Type type;
+ /**
+ * Input description.
+ *
+ */
+ @JsonProperty("description")
+ @JsonPropertyDescription("Input description.")
+ private String description;
+ /**
+ * A string contained in command-line, substituted by the input value and/or flag at runtime.
+ *
+ */
+ @JsonProperty("value-key")
+ @JsonPropertyDescription("A string contained in command-line, substituted by the input value and/or flag at runtime.")
+ private String valueKey;
+ /**
+ * True if input is a list of value. An input of type "Flag" cannot be a list.
+ *
+ */
+ @JsonProperty(value = "list")
+ @JsonPropertyDescription("True if input is a list of value. An input of type \"Flag\" cannot be a list.")
+ private Boolean list;
+ /**
+ * Separator used between list items. Defaults to a single space.
+ *
+ */
+ @JsonProperty("list-separator")
+ @JsonPropertyDescription("Separator used between list items. Defaults to a single space.")
+ private String listSeparator;
+ /**
+ * True if input is optional.
+ *
+ */
+ @JsonProperty("optional")
+ @JsonPropertyDescription("True if input is optional.")
+ private Boolean optional;
+ /**
+ * Option flag of the input, involved in the value-key substitution. Inputs of type "Flag" have to have a command-line flag. Examples: -v, --force.
+ *
+ */
+ @JsonProperty("command-line-flag")
+ @JsonPropertyDescription("Option flag of the input, involved in the value-key substitution. Inputs of type \"Flag\" have to have a command-line flag. Examples: -v, --force.")
+ private String commandLineFlag;
+ /**
+ * Ids of the inputs or ids of groups whose members must be active for this input to be available.
+ *
+ */
+ @JsonProperty("requires-inputs")
+ @JsonPropertyDescription("Ids of the inputs or ids of groups whose members must be active for this input to be available.")
+ private List requiresInputs = new ArrayList();
+ /**
+ * Ids of the inputs that are disabled when this input is active.
+ *
+ */
+ @JsonProperty("disables-inputs")
+ @JsonPropertyDescription("Ids of the inputs that are disabled when this input is active.")
+ private List disablesInputs = new ArrayList();
+ /**
+ * Separator used between flags and their arguments. Defaults to a single space.
+ *
+ */
+ @JsonProperty("command-line-flag-separator")
+ @JsonPropertyDescription("Separator used between flags and their arguments. Defaults to a single space.")
+ private String commandLineFlagSeparator;
+ /**
+ * Default value of the input. The default value is set when no value is specified, even when the input is optional. If the desired behavior is to omit the input from the command line when no value is specified, then no default value should be used. In this case, the tool might still use a default value internally, but this will remain undocumented in the Boutiques interface.
+ *
+ */
+ @JsonProperty("default-value")
+ @JsonPropertyDescription("Default value of the input. The default value is set when no value is specified, even when the input is optional. If the desired behavior is to omit the input from the command line when no value is specified, then no default value should be used. In this case, the tool might still use a default value internally, but this will remain undocumented in the Boutiques interface.")
+ private Object defaultValue;
+ /**
+ * Permitted choices for input value. May not be used with the Flag type.
+ *
+ */
+ @JsonProperty("value-choices")
+ @JsonPropertyDescription("Permitted choices for input value. May not be used with the Flag type.")
+ private List
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+ ${jackson.version}
+
+
diff --git a/vip-core/src/main/java/fr/insalyon/creatis/vip/core/client/VipException.java b/vip-core/src/main/java/fr/insalyon/creatis/vip/core/client/VipException.java
index 10ecc3994..1df521a1b 100644
--- a/vip-core/src/main/java/fr/insalyon/creatis/vip/core/client/VipException.java
+++ b/vip-core/src/main/java/fr/insalyon/creatis/vip/core/client/VipException.java
@@ -94,9 +94,12 @@ private static String format(String format, Object... args) {
return sb.toString();
}
- private Integer vipErrorCode = null;
+ private VipError vipError = null;
+ protected Optional getVipError() {
+ return Optional.ofNullable(vipError);
+ }
public Optional getVipErrorCode() {
- return Optional.ofNullable(vipErrorCode);
+ return getVipError().map(VipError::getCode);
}
// Allow all exception constructors to be used
@@ -120,17 +123,17 @@ public VipException(Throwable cause) {
public VipException(VipError vipError, Object ...params) {
super(formatMessage(vipError, params));
- this.vipErrorCode = vipError.getCode();
+ this.vipError = vipError;
}
public VipException(VipError vipError, Throwable cause, Object ...params) {
super(formatMessage(vipError, params), cause);
- this.vipErrorCode = vipError.getCode();
+ this.vipError = vipError;
}
public VipException(String message, VipError vipError) {
super(message);
- this.vipErrorCode = vipError.getCode();
+ this.vipError = vipError;
}
}
diff --git a/vip-core/src/main/java/fr/insalyon/creatis/vip/core/server/SpringCoreConfig.java b/vip-core/src/main/java/fr/insalyon/creatis/vip/core/server/SpringCoreConfig.java
index 2e19d3853..f4cc0de5e 100644
--- a/vip-core/src/main/java/fr/insalyon/creatis/vip/core/server/SpringCoreConfig.java
+++ b/vip-core/src/main/java/fr/insalyon/creatis/vip/core/server/SpringCoreConfig.java
@@ -1,5 +1,6 @@
package fr.insalyon.creatis.vip.core.server;
+import com.fasterxml.jackson.databind.ObjectMapper;
import fr.insalyon.creatis.grida.client.GRIDACacheClient;
import fr.insalyon.creatis.grida.client.GRIDAClient;
import fr.insalyon.creatis.grida.client.GRIDAPoolClient;
@@ -20,6 +21,7 @@
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePropertySource;
+import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy;
@@ -121,6 +123,11 @@ public SMAClient smaClient(Server server) {
return new SMAClient(server.getSMAHost(), server.getSMAPort());
}
+ @Bean
+ public ObjectMapper objectMapper() {
+ return Jackson2ObjectMapperBuilder.json().build();
+ }
+
// to verify the @Value injection existence
@Bean
public static PropertySourcesPlaceholderConfigurer properties(){
diff --git a/vip-core/src/test/java/fr/insalyon/creatis/vip/core/integrationtest/ServerMockConfig.java b/vip-core/src/test/java/fr/insalyon/creatis/vip/core/integrationtest/ServerMockConfig.java
index 65929ad07..c9091b4d8 100644
--- a/vip-core/src/test/java/fr/insalyon/creatis/vip/core/integrationtest/ServerMockConfig.java
+++ b/vip-core/src/test/java/fr/insalyon/creatis/vip/core/integrationtest/ServerMockConfig.java
@@ -2,6 +2,7 @@
import fr.insalyon.creatis.vip.core.server.business.Server;
import org.mockito.Mockito;
+import org.mockito.quality.Strictness;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@@ -9,8 +10,7 @@
import java.io.IOException;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
/**
* Spring configuration class for tests.
@@ -34,6 +34,10 @@ public class ServerMockConfig {
public static final String MAX_NUMBER_EXECUTIONS = "5";
public static final String TEST_CAS_URL = "testCasURL";
+ // paths stuff
+ public static final String TEST_USERS_ROOT = "/test/prefix/vip/data/test_users";
+ public static final String TEST_GROUP_ROOT = "/test/prefix/vip/data/test_groups";
+
public static void reset(Server server) {
Mockito.reset(server);
Mockito.when(server.getAdminFirstName()).thenReturn(TEST_ADMIN_FIRST_NAME);
@@ -45,15 +49,15 @@ public static void reset(Server server) {
Mockito.when(server.getTruststoreFile()).thenReturn(LAB_TRUSTSTORE_FILE);
Mockito.when(server.getTruststorePass()).thenReturn(LAB_TRUSTSTORE_PASS);
when(server.getMaxPlatformRunningSimulations()).thenReturn(Integer.valueOf(MAX_NUMBER_EXECUTIONS));
- when(server.getDataManagerUsersHome()).thenReturn("/test/prefix/vip/data/test_users");
- when(server.getDataManagerGroupsHome()).thenReturn("/test/prefix/vip/data/test_groups");
+ when(server.getDataManagerUsersHome()).thenReturn(TEST_USERS_ROOT);
+ when(server.getDataManagerGroupsHome()).thenReturn(TEST_GROUP_ROOT);
when(server.getVoRoot()).thenReturn("/vo_test/root");
}
@Bean
@Primary
public Server testServer() throws IOException {
- Server server = mock(Server.class);
+ Server server = mock(Server.class, withSettings().strictness(Strictness.STRICT_STUBS));
reset(server);
return server;
}
diff --git a/vip-core/src/test/java/UsersAndGroupsIT.java b/vip-core/src/test/java/fr/insalyon/creatis/vip/core/integrationtest/UsersAndGroupsIT.java
similarity index 99%
rename from vip-core/src/test/java/UsersAndGroupsIT.java
rename to vip-core/src/test/java/fr/insalyon/creatis/vip/core/integrationtest/UsersAndGroupsIT.java
index d6189837e..3e75544eb 100644
--- a/vip-core/src/test/java/UsersAndGroupsIT.java
+++ b/vip-core/src/test/java/fr/insalyon/creatis/vip/core/integrationtest/UsersAndGroupsIT.java
@@ -1,3 +1,5 @@
+package fr.insalyon.creatis.vip.core.integrationtest;
+
import fr.insalyon.creatis.grida.client.GRIDAClientException;
import fr.insalyon.creatis.vip.core.client.bean.Group;
import fr.insalyon.creatis.vip.core.client.bean.User;
diff --git a/vip-core/src/test/java/fr/insalyon/creatis/vip/core/integrationtest/database/BaseSpringIT.java b/vip-core/src/test/java/fr/insalyon/creatis/vip/core/integrationtest/database/BaseSpringIT.java
index f31af0609..0083f2d4d 100644
--- a/vip-core/src/test/java/fr/insalyon/creatis/vip/core/integrationtest/database/BaseSpringIT.java
+++ b/vip-core/src/test/java/fr/insalyon/creatis/vip/core/integrationtest/database/BaseSpringIT.java
@@ -13,6 +13,8 @@
import fr.insalyon.creatis.vip.core.server.business.Server;
import org.junit.jupiter.api.BeforeEach;
import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
@@ -25,6 +27,7 @@
import javax.sql.DataSource;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Date;
import java.util.List;
@@ -90,6 +93,7 @@ public abstract class BaseSpringIT {
@BeforeEach
protected void setUp() throws Exception {
ServerMockConfig.reset(server);
+ Mockito.reset(gridaClient);
}
protected void assertRowsNbInTable(String tableName, int expectedNb) {
@@ -102,27 +106,46 @@ protected void createUser(String testEmail) throws GRIDAClientException, Busines
createUser(testEmail, "");
}
+ protected void createUserWithPassword(String testEmail, String password) throws GRIDAClientException, BusinessException {
+ createUser(testEmail, "", password);
+ }
+
protected void createUser(String testEmail, String nameSuffix) throws GRIDAClientException, BusinessException {
+ createUser(testEmail, nameSuffix, "testPassword");
+ }
+
+ protected void createUser(String testEmail, String nameSuffix, String password) throws GRIDAClientException, BusinessException {
User newUser = new User("test firstName " + nameSuffix,
"test lastName " + nameSuffix, testEmail, "test institution",
- "testPassword", CountryCode.fr,
+ password, CountryCode.fr,
null);
Mockito.when(gridaClient.exist(anyString())).thenReturn(true, false);
configurationBusiness.signup(newUser, "", (Group) null);
}
+ protected void createUserInGroup(String userEmail, String groupName) throws BusinessException, GRIDAClientException {
+ createUserInGroup(userEmail, "", groupName);
+ }
+
protected void createUserInGroup(String userEmail, String nameSuffix, String groupName) throws BusinessException, GRIDAClientException {
+ createUserInGroups(userEmail, nameSuffix, groupName);
+ }
+
+ public void createGroup(String groupName) throws BusinessException {
+ configurationBusiness.addGroup(new Group(groupName, true, true, true));
+ }
+
+ protected void createUserInGroups(String userEmail, String nameSuffix, String... groupNames) throws BusinessException, GRIDAClientException {
User newUser = new User("test firstName " + nameSuffix,
"test lastName " + nameSuffix, userEmail, "test institution",
"testPassword", CountryCode.fr,
null);
Mockito.when(gridaClient.exist(anyString())).thenReturn(true, false);
- Group group = configurationBusiness.getGroup(groupName);
- configurationBusiness.signup(newUser, "", false, true, group);
- }
-
- protected void signInUser() throws BusinessException {
- configurationBusiness.signin("test1@test.fr", "testPassword");
+ List groups = new ArrayList<>();
+ for (String groupName : groupNames) {
+ groups.add(configurationBusiness.getGroup(groupName));
+ }
+ configurationBusiness.signup(newUser, "", false, true, groups);
}
protected Date getNextSecondDate() {
diff --git a/vip-core/src/test/java/fr/insalyon/creatis/vip/core/integrationtest/database/SpringJndiIT.java b/vip-core/src/test/java/fr/insalyon/creatis/vip/core/integrationtest/database/SpringJndiIT.java
index c1570a45e..a107acffc 100644
--- a/vip-core/src/test/java/fr/insalyon/creatis/vip/core/integrationtest/database/SpringJndiIT.java
+++ b/vip-core/src/test/java/fr/insalyon/creatis/vip/core/integrationtest/database/SpringJndiIT.java
@@ -2,6 +2,7 @@
import fr.insalyon.creatis.grida.client.GRIDAClient;
import fr.insalyon.creatis.grida.client.GRIDAClientException;
+import fr.insalyon.creatis.vip.core.client.bean.Account;
import fr.insalyon.creatis.vip.core.client.bean.Group;
import fr.insalyon.creatis.vip.core.client.bean.User;
import fr.insalyon.creatis.vip.core.client.view.util.CountryCode;
@@ -19,6 +20,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceUtils;
+import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
@@ -61,7 +63,6 @@
@TestPropertySource(properties = "db.tableEngine=") // to disable the default mysql/innodb engine on database init
@TestMethodOrder(OrderAnnotation.class)
@ActiveProfiles({"jndi-db", "test"}) // to use default jndi datasource but avoid default server config
-@Disabled
public class SpringJndiIT {
@Autowired
@@ -112,39 +113,39 @@ protected void doInTransactionWithoutResult(TransactionStatus status) {
}
/*
- Add an account
+ Add a group (there is already one after init)
+ */
@Test
@Order(2)
- public void addNewAccount() throws BusinessException {
- List accounts = configurationBusiness.getAccounts();
- assertEquals(0, accounts.size());
- configurationBusiness.addAccount("test Account", Collections.emptyList());
- accounts = configurationBusiness.getAccounts();
- assertEquals(1, accounts.size());
+ public void addNewGroup() throws BusinessException {
+ List groups = configurationBusiness.getGroups();
+ assertEquals(1, groups.size());
+ configurationBusiness.addGroup(new Group("test group", true, true, true));
+ groups = configurationBusiness.getGroups();
+ assertEquals(2, groups.size());
}
- */
/*
- Verify the account is still there
+ Verify the group is still there
+ */
@Test
@Order(3)
- public void isAccountStillThere() throws BusinessException {
- List accounts = configurationBusiness.getAccounts();
- assertEquals(1, accounts.size());
+ public void isGroupStillThere() throws BusinessException {
+ List groups = configurationBusiness.getGroups();
+ assertEquals(2, groups.size());
}
- */
/*
- Restart spring, account should still be there
+ Restart spring, group should still be there
+ */
@Test
@Order(4)
- @DirtiesContext(methodMode = MethodMode.BEFORE_METHOD) // to restart spring
- public void isAccountStillThereAfterRestart() throws BusinessException {
- List accounts = configurationBusiness.getAccounts();
- assertEquals(1, accounts.size());
+ @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) // to restart spring
+ public void isGroupStillThereAfterRestart() throws BusinessException {
+ List groups = configurationBusiness.getGroups();
+ assertEquals(2, groups.size());
}
- */
@Test
@Order(5)
diff --git a/vip-core/src/test/resources/jndi.properties b/vip-core/src/test/resources/jndi.properties
index 2ad299a7c..b832aefa3 100644
--- a/vip-core/src/test/resources/jndi.properties
+++ b/vip-core/src/test/resources/jndi.properties
@@ -1,5 +1,5 @@
-java.naming.factory.initial=org.osjava.sj.SimpleContextFactory
-org.osjava.sj.root=/$VIP_PROJECT_HOME/VIP-portal/vip-core/src/test/resources/jndi
+java.naming.factory.initial = org.osjava.sj.SimpleContextFactory
+org.osjava.sj.root=src/test/resources/simple-jndi-config
org.osjava.sj.space=java:comp/env
org.osjava.sj.jndi.shared=true
org.osjava.sj.delimiter=.
diff --git a/vip-core/src/test/resources/jndi/jdbc/vip.properties b/vip-core/src/test/resources/simple-jndi-config/jdbc/vip.properties
similarity index 100%
rename from vip-core/src/test/resources/jndi/jdbc/vip.properties
rename to vip-core/src/test/resources/simple-jndi-config/jdbc/vip.properties
diff --git a/vip-portal/pom.xml b/vip-portal/pom.xml
index 2a158c285..365981430 100644
--- a/vip-portal/pom.xml
+++ b/vip-portal/pom.xml
@@ -222,6 +222,12 @@ knowledge of the CeCILL-B license and that you accept its terms.
com.google.gwt
gwt-dev
provided
+
+
+ org.eclipse.jetty
+ *
+
+