Skip to content

Commit

Permalink
Release 2.1.0 (PR #302)
Browse files Browse the repository at this point in the history
Merge pull request #302 from virtual-imaging-platform/develop
  • Loading branch information
axlbonnet authored Sep 7, 2021
2 parents 6016063 + 76cd68c commit 33cd0a9
Show file tree
Hide file tree
Showing 88 changed files with 1,473 additions and 1,777 deletions.
55 changes: 51 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,55 @@ You may name your branch anything except master, develop, release-*, or hotfix-*
* Push your commits to Github (your fork).
* Make a pull request to merge feature branch (in your fork) to development branch (in the base repository).

# Installation instructions
# Production installation instructions

You can follow the instruction [here](https://github.com/virtual-imaging-platform/Complementary-tools/blob/develop/README.md)

You can contact us at [[email protected]]([email protected]) for precisions.

# Local test installation instructions

It is possible to launch a local vip instance in a tomcat on a linux machine.
This is only useful for testing purposes as most of the features are simulated and many are still to be implemented and do not work yet.
Here are the instructions to configure a local vip instance :
- create a empty folder that will contain all the configuration files and simulated data. `/path/to/vip/local/folder` will be its path used in the next instructions
- unzip the `local-config.zip` archive available in `vip-local/src/main/resources` in `/path/to/vip/local/folder`. This should contain 3 `.conf` files
- create a `$HOME/.vip` directory and a `$HOME/.vip/local-config-folder.properties` file
- put `vipConfigFolder = /path/to/vip/local/folder` in the `$HOME/.vip/local-config-folder.properties` file

Then, install vip in your local tomcat :

1. Build the vip-local war with `mvn clean package` at the root of the `VIP-portal` project.
2. Put the `vip-portal/target/vip-portal-[...]-local.war` file in the `$TOMCAT_HOME/webapps` directory
3. Add the folowing lines in `$TOMCAT_HOME/conf/context.xml` (database jndi configuration), and edit `path/to/vip/local/folder/vip` to the real path in `url`
```
<Resource name="jdbc/vip" auth="Container" type="javax.sql.DataSource"
username="sa"
password=""
driverClassName="org.h2.Driver"
description="VIP local h2 Connection"
url="jdbc:h2:/path/to/vip/local/folder/vip"
maxActive="100"
maxIdle="50" />
```
4. Create or adapt the `$TOMCAT_HOME/bin/setenv.sh` file with these lines (edit `path/to/vip/local/folder/vip` to the real path) :

```
export CATALINA_OPTS="$CATALINA_OPTS -Dspring.profiles.active=local,config-file,jndi-db"
export CATALINA_OPTS="$CATALINA_OPTS -DvipConfigFolder=/path/to/vip/local/folder"
```

5. That's it, start tomcat (`bin/startup.sh`). Access vip on `localhost:8080/vip-portal-[...]-local` (adapt with the war name and your tomcat host/port configuration)

### Local instance notes

- The default admin email/password is `[email protected]`/`localAdminPassword`.
- all is not working perfectly yet, expect to see some error messages. The home page, files transfers and execution launchs shoud work, but application imports and the page with execution details are not implemented at the moment.
- vip do not send email but logs them
- at the moment, logging is done in the `$HOME/.vip/vip.log` file






To be done. Until this section is written, install at your own risks or
contact us at
[[email protected]]([email protected]).
25 changes: 7 additions & 18 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ knowledge of the CeCILL-B license and that you accept its terms.
<properties>
<!-- project version. Only to change it here (and in CoreConstants.java
Follow this practice : https://maven.apache.org/maven-ci-friendly.html-->
<revision>2.0</revision>
<revision>2.1</revision>
<changelist/>
<sha1/>

Expand All @@ -57,6 +57,7 @@ knowledge of the CeCILL-B license and that you accept its terms.
<spring-framework.version>5.2.6.RELEASE</spring-framework.version>
<springsecurity.version>5.3.2.RELEASE</springsecurity.version>
<jackson.version>2.11.0</jackson.version>
<h2database.version>1.3.173</h2database.version>
</properties>

<description>VIP</description>
Expand Down Expand Up @@ -149,7 +150,7 @@ knowledge of the CeCILL-B license and that you accept its terms.
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.200</version>
<version>${h2database.version}</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down Expand Up @@ -192,21 +193,9 @@ knowledge of the CeCILL-B license and that you accept its terms.
<repositories>

<repository>
<id>creatis-releases</id>
<name>Creatis Insa Lyon repository [creatis]</name>
<url>http://vip.creatis.insa-lyon.fr:9007/nexus/content/repositories/releases</url>
</repository>

<repository>
<id>creatis-thirdparty</id>
<name>Creatis Insa Lyon repository [creatis]</name>
<url>http://vip.creatis.insa-lyon.fr:9007/nexus/content/repositories/thirdparty</url>
</repository>

<repository>
<id>creatis-snapshots</id>
<id>creatis</id>
<name>Creatis Insa Lyon repository [creatis]</name>
<url>http://vip.creatis.insa-lyon.fr:9007/nexus/content/repositories/snapshots</url>
<url>https://vip.creatis.insa-lyon.fr:9007/nexus/repository/public</url>
</repository>

<!-- repo used to get empty jar for commons logging and log4j -->
Expand All @@ -221,13 +210,13 @@ knowledge of the CeCILL-B license and that you accept its terms.
<repository>
<id>creatis-releases</id>
<name>Internal Releases</name>
<url>http://vip.creatis.insa-lyon.fr:9007/nexus/content/repositories/releases</url>
<url>https://vip.creatis.insa-lyon.fr:9007/nexus/repository/releases</url>
</repository>

<snapshotRepository>
<id>creatis-snapshots</id>
<name>Internal Snapshots</name>
<url>http://vip.creatis.insa-lyon.fr:9007/nexus/content/repositories/snapshots</url>
<url>https://vip.creatis.insa-lyon.fr:9007/nexus/repository/snapshots</url>
</snapshotRepository>

</distributionManagement>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,20 @@
*/
package fr.insalyon.creatis.vip.api;

import com.fasterxml.jackson.databind.ObjectMapper;
import fr.insalyon.creatis.vip.api.CarminProperties;
import fr.insalyon.creatis.vip.api.security.SpringCompatibleUser;
import fr.insalyon.creatis.vip.api.security.apikey.*;
import fr.insalyon.creatis.vip.api.security.apikey.ApikeyAuthenticationEntryPoint;
import fr.insalyon.creatis.vip.api.security.apikey.ApikeyAuthentificationConfigurer;
import fr.insalyon.creatis.vip.core.client.bean.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.*;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.firewall.DefaultHttpFirewall;
import org.springframework.security.web.firewall.StrictHttpFirewall;

import java.util.function.Supplier;

Expand All @@ -66,11 +63,15 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

// authentication done by bean LimitigDaoAuthenticationProvider

@Autowired
private ApikeyAuthenticationEntryPoint apikeyAuthenticationEntryPoint;
private final ApikeyAuthenticationEntryPoint apikeyAuthenticationEntryPoint;

private final Environment env;

@Autowired
private Environment env;
public SpringSecurityConfig(ApikeyAuthenticationEntryPoint apikeyAuthenticationEntryPoint, Environment env) {
this.apikeyAuthenticationEntryPoint = apikeyAuthenticationEntryPoint;
this.env = env;
}

@Override
protected void configure(HttpSecurity http) throws Exception {
Expand Down Expand Up @@ -110,11 +111,6 @@ public Supplier<User> currentUserProvider() {
};
}

@Bean
public ObjectMapper objectMapper() {
return Jackson2ObjectMapperBuilder.json().build();
}

/*
Do not use the default firewall (StrictHttpFirewall) because it blocks
"//" in url and it is used in gwt rpc calls
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
*/
package fr.insalyon.creatis.vip.api;

import com.fasterxml.jackson.databind.ObjectMapper;
import fr.insalyon.creatis.vip.api.business.VipConfigurer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
Expand All @@ -43,6 +44,7 @@
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.ResourcePropertySource;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.web.servlet.config.annotation.*;

import java.io.IOException;
Expand Down Expand Up @@ -102,4 +104,8 @@ public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(vipConfigurer);
}

@Bean
public ObjectMapper objectMapper() {
return Jackson2ObjectMapperBuilder.json().build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

import fr.insalyon.creatis.vip.api.CarminProperties;
import fr.insalyon.creatis.vip.api.exception.ApiException;
import fr.insalyon.creatis.vip.api.exception.ApiException.ApiError;
import fr.insalyon.creatis.vip.api.model.PathProperties;
import fr.insalyon.creatis.vip.api.model.UploadData;
import fr.insalyon.creatis.vip.api.model.UploadDataType;
Expand Down Expand Up @@ -281,12 +282,13 @@ private void checkDownloadPermission(String path) throws ApiException {
private void checkPermission(String path, LFCAccessType accessType)
throws ApiException {
try {
lfcPermissionBusiness.checkPermission(
currentUserProvider.get(), path, accessType);
if ( ! lfcPermissionBusiness.isLFCPathAllowed(
currentUserProvider.get(), path, accessType, true)) {
throw new ApiException(ApiError.UNAUTHORIZED_DATA_ACCESS, path);
}
} catch (BusinessException e) {
throw new ApiException("API Permission error", e);
throw new ApiException("Error when checking permissions", e);
}
// all check passed : all good !
}

// #### DOWNLOAD STUFF
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ public enum ApiError implements VipError{
INPUT_FIELD_NOT_VALID(8009),
WRONG_DATE_FORMAT(8010),
WRONG_STAT_SERVICE(8011),
COUNTRY_UNKNOWN(8012);
COUNTRY_UNKNOWN(8012),
UNAUTHORIZED_DATA_ACCESS(8013);

private Integer code;
ApiError(Integer code) { this.code = code; }
Expand All @@ -75,6 +76,7 @@ public enum ApiError implements VipError{
addMessage(ApiError.WRONG_DATE_FORMAT, "The date {} have a wrong format (needed : {})", 2);
addMessage(ApiError.WRONG_STAT_SERVICE, "The service {} is unknown, only 'vip' is possible", 1);
addMessage(ApiError.COUNTRY_UNKNOWN, "Country unknown : {}", 1);
addMessage(ApiError.UNAUTHORIZED_DATA_ACCESS, "Unauthorized data access to : {}", 1);
}

public Optional<String> getMessage() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public class ApikeyAuthenticationEntryPoint implements AuthenticationEntryPoint

private final ObjectMapper objectMapper;

@Autowired
public ApikeyAuthenticationEntryPoint(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ public static ApplicationImporterServiceAsync getInstance() {

String readAndValidateBoutiquesFile(String fileLFN) throws ApplicationImporterException;

void createApplication(BoutiquesTool bt, String type, String tag, HashMap<String, BoutiquesTool> bts, boolean isRunOnGrid, boolean overwriteVersion, boolean challenge) throws ApplicationImporterException;
void createApplication(BoutiquesTool bt, String type, String tag, boolean isRunOnGrid, boolean overwriteVersion) throws ApplicationImporterException;

String getApplicationImporterRootFolder() throws ApplicationImporterException;

List<String> getApplicationImporterRequirements() throws ApplicationImporterException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public interface ApplicationImporterServiceAsync {

public void readAndValidateBoutiquesFile(String fileLFN, AsyncCallback<String> callback);

public void createApplication(BoutiquesTool bt, String type, String tag, HashMap<String, BoutiquesTool> bts, boolean isRunOnGrid, boolean overwriteVersion, boolean challenge, AsyncCallback<Void> callback);
public void createApplication(BoutiquesTool bt, String type, String tag, boolean isRunOnGrid, boolean overwriteVersion, AsyncCallback<Void> callback);

public void getApplicationImporterRootFolder(AsyncCallback<String> asyncCallback);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,8 @@ public class Constants {
public static final String VM_GASW = "gasw.vm";
//LFN access to SegPerfAnalyzer
public static final String LNF_PATH = "";
// Application Importer Challenge Descriptor Path
public static final String APP_IMPORTER_CHALLENGE_PATH_MSSEG = "/vip/MSEG-admin/applications/templates";
public static final String APP_IMPORTER_CHALLENGE_PATH_PETSEG = "/vip/PETSEG-admin/applications/templates";
// Application Importer Challenge Descriptor
public static final String APP_IMPORTER_CHALLENGE_METRIC = "SegPerfAnalyzer.json";
public static final String APP_IMPORTER_CHALLENGE_METADATA = "metadata-updater.json";
// Application Importer types
public static final String APP_IMPORTER_STANDALONE_TYPE = "app-importer-standalone-type";
public static final String APP_IMPORTER_DOT_INPUTS_TYPE = "app-importer-dot-inputs-type";

}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ public class DisplayTab extends Tab {
private VIPLayout vipLayout;
private final ModalWindow modal;
private BoutiquesTool boutiquesTool;
private HashMap<String, BoutiquesTool> bts = null;

public DisplayTab(String tabIcon, String tabId, String tabName) {
this.setTitle(Canvas.imgHTML(tabIcon) + " " + tabName.trim());
Expand Down Expand Up @@ -107,70 +106,13 @@ private void configure() {
@Override
public void onClick(ClickEvent event) {
boutiquesTool.setApplicationLFN(vipLayout.getApplicationLocation() + "/" + boutiquesTool.getName());
if (!vipLayout.getApplicationType().contains("standalone")) {
createApplicationWithAddDesc();
} else {
createApplication();
}

createApplication();
}
});
createApplicationButton.setWidth(120);
globalLayout.addMember(createApplicationButton);
}

/**
* Creates an application depending on other descriptors for the MICCAI
* challenge. The results of application should be evaluated to different
* metric methods.
*
*/
public void createApplicationWithAddDesc() {
bts = new HashMap<String, BoutiquesTool>();
// Fisrt callback to get mectric descriptor
final AsyncCallback<String> callback = new AsyncCallback<String>() {
@Override
public void onFailure(Throwable caught) {
Layout.getInstance().setWarningMessage("Unable to read JSON file :" + caught.getMessage());
}

@Override
public void onSuccess(String jsonFileContent) {
try {
bts.put("metric", JSONUtil.parseBoutiquesTool(JSONParser.parseStrict(jsonFileContent).isObject()));
bts.get("metric").setApplicationLFN(vipLayout.getApplicationLocation() + "/" + boutiquesTool.getName());

//second callback to get metadata descripotr
final AsyncCallback<String> callback2 = new AsyncCallback<String>() {
@Override
public void onFailure(Throwable caught) {
Layout.getInstance().setWarningMessage("Unable to read JSON file :" + caught.getMessage());
}

@Override
public void onSuccess(String jsonFileContent) {
try {
bts.put("adaptater", JSONUtil.parseBoutiquesTool(JSONParser.parseStrict(jsonFileContent).isObject()));
bts.get("adaptater").setApplicationLFN(vipLayout.getApplicationLocation() + "/" + boutiquesTool.getName());
//Finally, launch
createApplication();
} catch (ApplicationImporterException ex) {
Logger.getLogger(DisplayTab.class.getName()).log(Level.SEVERE, null, ex);
}

}
};
ApplicationImporterService.Util.getInstance().readAndValidateBoutiquesFile(vipLayout.getDescriptorLocation() + "/" + Constants.APP_IMPORTER_CHALLENGE_METADATA,
callback2);
} catch (ApplicationImporterException ex) {
Logger.getLogger(DisplayTab.class.getName()).log(Level.SEVERE, null, ex);
}

}
};
ApplicationImporterService.Util.getInstance().readAndValidateBoutiquesFile(vipLayout.getDescriptorLocation() + "/" + Constants.APP_IMPORTER_CHALLENGE_METRIC, callback);
}

public static BoutiquesTool parseJSON(JSONObject jsonObject)
throws ApplicationImporterException {

Expand Down Expand Up @@ -232,10 +174,8 @@ public void onSuccess(Void result) {
boutiquesTool,
vipLayout.getApplicationType(),
vipLayout.getTag(),
bts,
vipLayout.getIsRunOnGrid(),
vipLayout.getOverwrite(),
false,
callback);
}
}
Loading

0 comments on commit 33cd0a9

Please sign in to comment.