Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions doc/sphinx-guides/source/installation/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,29 @@ Enabling a second authentication provider will result in the Log In page showing
- ``:AllowSignUp`` is set to "false" per the :doc:`config` section to prevent users from creating local accounts via the web interface. Please note that local accounts can also be created via API, and the way to prevent this is to block the ``builtin-users`` endpoint or scramble (or remove) the ``BuiltinUsers.KEY`` database setting per the :doc:`config` section.
- The "builtin" authentication provider has been disabled. Note that disabling the builting auth provider means that the API endpoint for converting an account from a remote auth provider will not work. This is the main reason why https://github.com/IQSS/dataverse/issues/2974 is still open. Converting directly from one remote authentication provider to another (i.e. from GitHub to Google) is not supported. Conversion from remote is always to builtin. Then the user initiates a conversion from builtin to remote. Note that longer term, the plan is to permit multiple login options to the same Dataverse account per https://github.com/IQSS/dataverse/issues/3487 (so all this talk of conversion will be moot) but for now users can only use a single login option, as explained in the :doc:`/user/account` section of the User Guide. In short, "remote only" might work for you if you only plan to use a single remote authentication provider such that no conversion between remote authentication providers will be necessary.

Swift Installation
------------------

On every generic Dataverse installation, datafiles are stored in local storage. You can opt for a experimental dataverse installation with a Swift Object Storage backend instead. Each dataset that you create is saved as a container. Each datafile is saved as a file within the container.

In order to configure a Swift installation, there are two steps you need to complete before running the installer:

First, you need to add a file called swift.properties in ``/glassfish4/glassfish/domains/domain1/config``. It needs to be configured as follows:

.. code-block:: none
swift.default.endpoint=endpoint1
swift.auth_url.endpoint1=your-auth-url
swift.tenant.endpoint1=your-tenant-name
swift.username.endpoint1=your-username
swift.password.endpoint1=your-password
swift.auth_type.endpoint1=your-authentication-type
swift.swift_endpoint.endpoint1=your-swift-endpoint

where authentication type can either be "keystone" (without the quotes) or it will assumed to be basic. Additionally, authentication url should be your keystone authentication url which includes the tokens. For example, https://dataverse.org:35357/v2.0/tokens.

Second, you need to update the JVM option ``dataverse.files.storage-driver-id``. You can do this by running the delete command ``./asadmin $ASADMIN_OPTS delete-jvm-options "\-Ddataverse.files.storage-driver-id=file"`` and then the create command ``./asadmin $ASADMIN_OPTS create-jvm-options "\-Ddataverse.files.storage-driver-id=swift"``.


JVM Options
-----------

Expand Down Expand Up @@ -188,6 +211,11 @@ dataverse.files.directory

This is how you configure the path to which files uploaded by users are stored.

dataverse.files.storage-driver-id
+++++++++++++++++++++++++++++++++

Initialized to file, this is what you would change if you were interested in a Swift backend for your installation. See above in the Swift Installation section.

dataverse.auth.password-reset-timeout-in-minutes
++++++++++++++++++++++++++++++++++++++++++++++++

Expand Down
24 changes: 22 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -319,17 +319,31 @@
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.5.201505241946</version>
</dependency>
<!-- Added specific versionf of SLF4J jars; otherwise we end up with
conflicting versions of slf4j-api and slf4j-log4j12, loaded as
dependencies for different packages; which was causing some incompatibility
issues -L.A. 4.3 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.10.19</version>
</dependency>
<!-- Added for DataCite -->
<dependency>
<!--dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
</dependency -->
<dependency>
<groupId>axis</groupId>
<artifactId>axis</artifactId>
Expand All @@ -355,6 +369,12 @@
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency>
<!-- JavaSwift/JOSS: for accessing OpenStack cloud storage -->
<dependency>
<groupId>org.javaswift</groupId>
<artifactId>joss</artifactId>
<version>0.9.10</version>
</dependency>
<dependency>
<groupId>com.maxmind.geoip2</groupId>
<artifactId>geoip2</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/edu/harvard/iq/dataverse/DataFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ public String getOriginalChecksumType() {
}

public DataFileIO getAccessObject() throws IOException {
DataFileIO dataAccess = DataAccess.createDataAccessObject(this);
DataFileIO dataAccess = DataAccess.getDataFileIO(this);

if (dataAccess == null) {
throw new IOException("Failed to create access object for datafile.");
Expand Down
16 changes: 15 additions & 1 deletion src/main/java/edu/harvard/iq/dataverse/FilePage.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package edu.harvard.iq.dataverse;

import edu.harvard.iq.dataverse.DatasetVersionServiceBean.RetrieveDatasetVersionResponse;
import edu.harvard.iq.dataverse.dataaccess.SwiftAccessIO;
import edu.harvard.iq.dataverse.authorization.AuthenticationServiceBean;
import edu.harvard.iq.dataverse.authorization.Permission;
import edu.harvard.iq.dataverse.datasetutility.TwoRavensHelper;
Expand Down Expand Up @@ -616,7 +617,20 @@ public boolean isPubliclyDownloadable() {
}

public String getPublicDownloadUrl() {
return FileUtil.getPublicDownloadUrl(systemConfig.getDataverseSiteUrl(), fileId);
if (System.getProperty("dataverse.files.storage-driver-id").equals("swift")) {
String fileDownloadUrl = null;
try {
SwiftAccessIO swiftIO = (SwiftAccessIO) getFile().getAccessObject();
swiftIO.open();
fileDownloadUrl = swiftIO.getRemoteUrl();
logger.info("Swift url: " + fileDownloadUrl);
} catch (Exception e) {
e.printStackTrace();
}
return fileDownloadUrl;
} else {
return FileUtil.getPublicDownloadUrl(systemConfig.getDataverseSiteUrl(), fileId);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public void writeTo(BundleDownloadInstance di, Class<?> clazz, Type type, Annota
if (di.getDownloadInfo() != null && di.getDownloadInfo().getDataFile() != null) {
DataAccessRequest daReq = new DataAccessRequest();
DataFile sf = di.getDownloadInfo().getDataFile();
DataFileIO accessObject = DataAccess.createDataAccessObject(sf, daReq);
DataFileIO accessObject = DataAccess.getDataFileIO(sf, daReq);

if (accessObject != null) {
accessObject.open();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public void writeTo(DownloadInstance di, Class<?> clazz, Type type, Annotation[]


DataFile sf = di.getDownloadInfo().getDataFile();
DataFileIO accessObject = DataAccess.createDataAccessObject(sf, daReq);
DataFileIO accessObject = DataAccess.getDataFileIO(sf, daReq);

if (accessObject != null) {
accessObject.open();
Expand Down
77 changes: 68 additions & 9 deletions src/main/java/edu/harvard/iq/dataverse/dataaccess/DataAccess.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
package edu.harvard.iq.dataverse.dataaccess;

import edu.harvard.iq.dataverse.DataFile;

import java.io.IOException;
import org.javaswift.joss.model.StoredObject;

/**
*
Expand All @@ -34,21 +34,32 @@ public DataAccess() {

}

public static DataFileIO createDataAccessObject (DataFile df) throws IOException {
return createDataAccessObject (df, null);
// set by the user in glassfish-setup.sh if DEFFAULT_STORAGE_DRIVER_IDENTIFIER = swift
public static final String DEFAULT_STORAGE_DRIVER_IDENTIFIER = System.getProperty("dataverse.files.storage-driver-id");
public static String swiftFileUri;

// The getDataFileIO() methods initialize DataFileIO objects for
// datafiles that are already saved using one of the supported Dataverse
// DataAccess IO drivers.
public static DataFileIO getDataFileIO(DataFile df) throws IOException {
return getDataFileIO(df, null);
}

public static DataFileIO createDataAccessObject (DataFile df, DataAccessRequest req) throws IOException {
public static DataFileIO getDataFileIO(DataFile df, DataAccessRequest req) throws IOException {

if (df == null ||
df.getStorageIdentifier() == null ||
df.getStorageIdentifier().equals("")) {
throw new IOException ("createDataAccessObject: null or invalid datafile.");
if (df == null
|| df.getStorageIdentifier() == null
|| df.getStorageIdentifier().equals("")) {
throw new IOException("getDataAccessObject: null or invalid datafile.");
}

if (df.getStorageIdentifier().startsWith("file://")
|| (!df.getStorageIdentifier().matches("^[a-z][a-z]*://.*"))) {
return new FileAccessIO (df, req);
} else if (df.getStorageIdentifier().startsWith("swift://")){
return new SwiftAccessIO(df, req);
} else if (df.getStorageIdentifier().startsWith("tmp://")) {
throw new IOException("DataAccess IO attempted on a temporary file that hasn't been permanently saved yet.");
}

// No other storage methods are supported as of now! -- 4.0.1
Expand All @@ -58,6 +69,54 @@ public static DataFileIO createDataAccessObject (DataFile df, DataAccessRequest
// "storage identifier".
// -- L.A. 4.0.2

throw new IOException ("createDataAccessObject: Unsupported storage method.");
throw new IOException("getDataAccessObject: Unsupported storage method.");
}

// createDataAccessObject() methods create a *new*, empty DataAccess objects,
// for saving new, not yet saved datafiles.
public static DataFileIO createNewDataFileIO(DataFile df, String storageTag) throws IOException {

return createNewDataFileIO(df, storageTag, DEFAULT_STORAGE_DRIVER_IDENTIFIER);
}

public static DataFileIO createNewDataFileIO(DataFile df, String storageTag, String driverIdentifier) throws IOException {
if (df == null
|| storageTag == null
|| storageTag.equals("")) {
throw new IOException("getDataAccessObject: null or invalid datafile.");
}

DataFileIO dataFileIO = null;

df.setStorageIdentifier(storageTag);

if (driverIdentifier == null) {
driverIdentifier = "file";
}

if (driverIdentifier.equals("file")) {
dataFileIO = new FileAccessIO(df, null);
} else if (driverIdentifier.equals("swift")) {
dataFileIO = new SwiftAccessIO(df, null);
} else {
throw new IOException("createDataAccessObject: Unsupported storage method " + driverIdentifier);
}

dataFileIO.open(DataAccessOption.WRITE_ACCESS);
return dataFileIO;
}

public static String getSwiftFileURI(StoredObject fileObject) throws IOException {
String fileUri;
try {
fileUri = fileObject.getPublicURL();
} catch (Exception ex) {
ex.printStackTrace();
throw new IOException("SwiftAccessIO: failed to get file storage location");
}
return fileUri;
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ public long addFileToZipStream(DataFile dataFile) throws IOException {
boolean createManifest = fileManifest != null;

DataAccessRequest daReq = new DataAccessRequest();
DataFileIO accessObject = DataAccess.createDataAccessObject(dataFile, daReq);
DataFileIO accessObject = DataAccess.getDataFileIO(dataFile, daReq);

if (accessObject != null) {
accessObject.open();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ public static String getImageThumbAsBase64(DataFile file, int size) {
try {

fileAccess = (FileAccessIO) file.getAccessObject();
} catch (ClassCastException ex) {
logger.warning("Unable to cast file id " + file.getId() + " from DataFileIO to FileAccessIO.");
return null;
} catch (IOException ex) {
// too bad - but not fatal
logger.warning("getImageThumbAsBase64: Failed to obtain FileAccess object for DataFile id " + file.getId());
Expand Down
Loading