1. Audience
This Project aims at Developers who wants to enable their SpringBoot Application to be authenticated against an Owncloud Instance and use the Owncloud Provisioning API.
It’s planned to implement the following additional API’s of Owncloud:
-
Subadmins (via User Provisioning API)
-
App Management (via User Provisioning API)
2. Changelog
2.1. 1.4.0
-
BUGFIX: Thread-Deadlock on calling
close()
twice onPipedInputStream
orPipedOutputStream
-
UPDATE: updated to Version
2.0.3.RELEASE
of Spring Boot and other Dependency updates
3. Quick Start
3.1. Maven Dependency
Add the following Maven Dependency:
<dependency>
<groupId>software.coolstuff</groupId>
<artifactId>owncloud-spring-boot-starter</artifactId>
<version>1.5.0</version>
</dependency>
3.2. Application Properties
Add the following Property:
owncloud.location=https://www.example.com/owncloud
3.3. Test your Application
When you now run your Spring-Boot Application the following Login-Screen appears:
Provide your Owncloud User Credentials and you are now able to work with your Application.
4. What’s included
This Spring-Boot Starter provides the following Functionalities:
-
simple Auto-Configuration
-
add it as a Maven Dependency
-
configure the Server-Address as a Spring-Boot Application-Property
-
-
Authenticate against one Owncloud Instance by using the Spring Security Authentication Mechanism
-
Get Information about the authenticated User
-
Modify the granted Authorities during the Authentication Process
-
Get User Information (Display-Name, eMail) of the authenticated User
-
Modify the User Information (Display-Name, eMail) of the authenticated User
-
Get the assigned Groups of the authenticated User
-
additional Enhancements as an Administrator:
-
Query all Users of the Owncloud Instance (optional with Filter by DisplayName)
-
Query all Groups of the Owncloud Instance (optional with Filter by Group Name)
-
Get detailed Information about one User by its Username
-
Modify the User Information of any User
-
Create new Users
-
Delete Users
-
Get the Group Memberships of any User
-
Modify the Group Memberships of any User
-
Get the User Memberships of any Group
-
get File Quota Information about any User
-
-
InMemory Owncloud Instance
-
Read Data as XML from
-
a Classpath Resource (read only) or
-
an external File Resource (read write)
-
-
Useful for local Development
-
Useful for Unit Tests / Integration Tests
-
-
save any type of File on the Owncloud
-
delete existing Files on the Owncloud
-
create/modify/delete Subdirectories
-
get File Quota Information about the authenticated User
5. Prerequisites
The following Prerequisites must be met in Order to work with this Spring-Boot Starter:
-
Owncloud Instance must be installed, configured and running.
-
The Owncloud Instance must have at least Version 8
-
You must be able to connect to this Owncloud Instance (i.E. Firewall-Settings, Network, …)
-
The Provisioning API must be enabled
6. Configuration
All Services of this Spring-Boot Starter will be managed by the following Configuration Parameters.
Name | available for | mandatory | Data Type | Default | Description |
---|---|---|---|---|---|
owncloud.location |
- |
true |
String |
- |
The Location of the Owncloud Instance |
owncloud.user-service.enable-modifications |
- |
false |
boolean |
|
Modifications through |
owncloud.resource-service.add-relative-down-path |
- |
true |
boolean |
|
add |
owncloud.resource-service.piped-stream-buffer-size |
- |
true |
Integer |
8192 |
Buffer Size (in Bytes) for Content-Streaming (InputStream/OutputStream) |
owncloud.resource-service.piped-stream-uncaught-exception-log-level |
- |
true |
LogLevel |
|
Log Level for any uncaught Exceptions while Content-Streaming |
owncloud.resource-service.sardine-cache.concurrency-level |
REST |
false |
Integer |
- |
Concurrency Level for the Sardine Cache (look at Guava CacheBuilder |
owncloud.resource-service.sardine-cache.expire-after-access |
REST |
false |
Long |
- |
Duration of Availability of the cached Sardine-Implementation after the last Access (see Guava CacheBuilder |
owncloud.resource-service.sardine-cache.expire-after-access-time-unit |
REST |
false |
java.util.concurrent.TimeUnit |
TimeUnit.SECONDS |
Timeunit for |
owncloud.resource-service.sardine-cache.expire-after-write |
REST |
false |
Long |
- |
Duration of Availability of the cached Sardine-Implementation after Write (see Guava CacheBuilder |
owncloud.resource-service.sardine-cache.expire-after-write-time-unit |
REST |
false |
java.util.concurrent.TimeUnit |
TimeUnit.SECONDS |
Timeunit for |
owncloud.resource-service.sardine-cache.initial-capacity |
REST |
false |
Integer |
- |
Initial Capacity of the Sardine Cache (see Guava CacheBuilder |
owncloud.resource-service.sardine-cache.maximum-size |
REST |
false |
Long |
- |
Maximum Size of the Sardine Cache (see Guava CacheBuilder |
owncloud.resource-service.sardine-cache.maximum-weight |
REST |
false |
Long |
- |
Maximum Weight of the Entries within the Sardine Cache (see Guava CacheBuilder |
owncloud.resource-service.sardine-cache.refresh-after-write |
REST |
false |
Long |
- |
Duration when the Entries of the Sardine-Cache should be refreshed after Write (see Guava CacheBuilder |
owncloud.resource-service.sardine-cache.refresh-after-write-time-unit |
REST |
false |
java.util.concurrent.TimeUnit |
TimeUnit.SECONDS |
Timeunit for |
owncloud.resource-service.message-digest-algorithm |
LOCAL |
true |
OwncloudLocalProperties.ResourceServiceProperties.MessageDigestAlgorithm |
MessageDigestAlgorithm.MD5 |
Message Digest Algorithm for the Checksum Service |
owncloud.resource-service.location |
LOCAL |
true |
java.nio.file.Path |
- |
Root-Path of the local Files to be served by the |
owncloud.resource-service.piped-stream-temporary-file-prefix |
LOCAL |
true |
String |
owncloud |
File Prefix used for temporary Files by |
6.1. owncloud.location
The Configuration Parameter owncloud.location
defines, which Backend will be used.
It can have one of the following Values:
starts with | modifiable | Description |
---|---|---|
|
true |
The Authentication uses the Owncloud of this Web-Address |
|
false |
Get Data of an In-Memory Owncloud Instance from a Classpath Resource |
|
true |
Get Data of an In-Memory Owncloud Instance from an external File Resource |
Normally you would provide the Web-Address of the Owncloud-Instance. But for local Development or Tests it could be useful, to have an Owncloud Instance which always behaves the same (returns the same Users, the same Groups, …).
There you can define a XML-Resource with either classpath:
or file:
.
This XML-Resource should have the following Format:
<owncloud>
<users> (1)
<user> (2)
<username>user1</username> (3)
<password>s3cr3t</password> (4)
<enabled>true</enabled>
<displayname>Mr. User 1</displayname> (5)
<email>user1@example.com</email>
<groups> (6)
<group>group1</group>
<group>group2</group>
</groups>
<quota>10240</quota> (7)
</user>
<user>
<username>user2</username>
<password>s3cr3t</password>
<enabled>false</enabled>
<displayName>Mrs. User 2</displayName>
<email>user2@example.com</email>
</user>
</users>
<groups> (8)
<group>group1</group>
<group>group2</group>
<group>group3</group>
</groups>
</owncloud>
-
List of all existing Users
-
The Definition of a single User
-
Username, Password and Availability-Stats (
<enabled>
) are mandatory. -
unencrypted Password (because you’re in local Development or Test Environment)
-
optional Parameters
-
Group Memberships of the User.
-
File Quota of the User (in Bytes). If omitted the User has unlimited Quota on the File-System.
-
All available Groups of the InMemory Owncloud Instance
Note
|
All Groups, which are referenced as a User-Membership will be checked
when the Service starts. If there are any Groups, which are not defined at the <groups> Section
the Service will fail on Startup with an IllegalStateException .
|
So if you define the Configuration Parameter owncloud.location
either as
-
classpath:/path/to/owncloud.xml
or -
file:/path/to/owncloud.xml
the Data of the provided XML-File will be read on Application Startup and resist as a InMemory Representation used by the Services of this Spring-Boot Starter (Authentication, UserQuery, UserModification, …).
When you use a file:
Resource the changed Data will be rewritten to this Resource on a normal Shutdown
of the Application. This is useful for incremental Integration Tests.
When you use a classpath:
Resource the changed Data will not be written. Therefor this type should be used
for local Development and/or Unit Tests.
7. Authentication
The Authentication has been implemented as a Spring Security AutheticationProvider
.
Due to the AutoConfiguration
Feature this AuthenticationProvider will be automatically loaded and configured when the Configuration Parameter owncloud.location
has been set.
7.1. Configuration
By including owncloud-spring-boot-starter
into the Classpath this Authentication-Provider is autoconfigured unless you decide to Overwrite it (by instantiating your own Implementation as a Subclass of OwncloudAuthenticationProvider
).
If this is the only Authentication-Provider existing then Spring-Boot will use this Authentication-Provider.
When you have several Authentication-Provider instantiated then you have to configure its Usage by a WebSecurityConfigurerAdapter
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@EnableWebSecurity
public class MyWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("owncloudAuthenticationProvider")
private AuthenticationProvider authenticationProvider;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
}
}
By the Qualifier owncloudAuthenticationProvider
you can inject the Owncloud Authentication Provider directly into the WebSecurityConfigurerAdapter
and use this AuthenticationProvider for Authentication.
7.2. RememberMe Services
Unfortunatly RememberMe Service is not available for Owncloud Authentication. Like Microsoft ActiveDirectory the Owncloud Instance doesn’t provide the Password of a User which is necessary for InMemory RememberMe Services.
Also the RememberMe-Services based on Persistent Tokens will not work because you need the Password of the Owncloud User for all Requests to the Owncloud. This could only be provided, if the original Session is available
(and not reauthenticated by the RememberMe Service).
Maybe one time Owncloud will provide an Application Token or work as a OAuth Provider. But this will be future work.
7.3. Groups vs. Authorities
A Group in Owncloud is mostly a Summary of Privileges the User has been granted to (Shares, Calendars, Addressbooks, …)
An Authority is, simple said, a Set of Privileges, which you can test upon the Call of a Method.
A Owncloud Group wont represent a simple Authority instead a Group of Authorities.
Therefor you can map the Groups of the Owncloud User to Authorities needed by your Application in 2 Ways.
7.3.1. GrantedAuthoritiesMapper
With the help of a GrantedAuthoritiesMapper
you can map the Owncloud Groups of the User to Authorities you can use within your Application. The simplest of them is the SimpleAuthorityMapper
which prepends a Prefix ROLE_
to the Owncloud Group Name.
You simply add the GrantedAuthoritiesMapper
as a Spring Bean:
@Configuration
public class MyConfiguration {
@Bean
public GrantedAuthoritiesMapper grantedAuthoritiesMapper() {
return new SimpleGrantedAuthoritiesMapper();
}
}
Up now all Groups of the User will be added with the Prefix ROLE_
and added as an Authority to the List of Authorities of the Authentication Object.
7.3.2. OwncloudGrantedAuthoritiesMapper
In Spring Security there exists a good Database Schema for the Relationship between Users, Groups and Authorities:
Following this Schema there are 2 Kinds of Classes involved
-
User
,Group
&UserGroup
are managed by Owncloud -
Authority
,UserAuthority
&GroupAuthority
are managed by your Application
A Spring Bean of OwncloudGrantedAuthoritiesMapper
matches your Authorities to the authenticated User during the Authentication Process.
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Service;
import software.coolstuff.springframework.owncloud.service.api.OwncloudGrantedAuthoritiesMapper;
@Service
public class MyOwncloudGrantedAuthoritiesMapper implements OwncloudGrantedAuthoritiesMapper {
private final static String ROLE_PREFIX = "ROLE_";
@Autowired
private UserAuthorityRepository userAuthorityRepository;
@Autowired
private GroupAuthorityRepository groupAuthorityRepository;
@Override
public Collection<? extends GrantedAuthority> mapAuthorities(
String username,
Collection<? extends GrantedAuthority> grantedAuthorities) {
Set<GrantedAuthority> authorities = new HashSet<>();
addAllAuthorities(userAuthorityRepository.getAuthorities(username), authorities);
if (CollectionUtils.isNotEmpty(grantedAuthorities)) {
for (GrantedAuthority grantedAuthority : grantedAuthorities) {
List<ApplicationAuthority> groupAuthorities =
groupAuthorityRepository.getAuthorities(grantedAuthority.getAuthority());
addAllAuthorities(groupAuthorities, authorities);
}
}
return authorities;
}
private void addAllAuthorities(
Collection<ApplicationAuthority> applicationAuthorities,
Set<GrantedAuthority> springSecurityAuthorities) {
if (CollectionUtils.isEmpty(applicationAuthorities)) {
return;
}
for (ApplicationAuthority applicationAuthority : applicationAuthorities) {
GrantedAuthority springSecurityAuthority =
new SimpleGrantedAuthority(applicationAuthority.getName());
if (!StringUtils.startsWith(applicationAuthority.getName(), ROLE_PREFIX)) {
springSecurityAuthority =
new SimpleGrantedAuthority(ROLE_PREFIX + applicationAuthority.getName());
}
springSecurityAuthorities.add(springSecurityAuthority);
}
}
}
By the assumption that
-
Class
ApplicationAuthority
simply returns the Authority by MethodgetName()
-
Class
UserAuthorityRepository
returns a List ofApplicationAuthority
by MethodgetAuthorities(String username)
-
Class
GroupAuthorityRepository
returns a List ofApplicationAuthority
by MethodgetAuthorities(String groupname)
this Class returns all Authorities for the Owncloud User username
and its associated Groups (authorities
).
8. UserDetails Service
Like the Authentication Provider the OwncloudUserDetailsService
will be autoconfigured by including owncloud-spring-boot-starter
into your Classpath.
The OwncloudUserDetailsService
will be used by OwncloudAuthenticationProvider
to load the UserDetails of the authenticated User. This is necessary to identify the Enabled/Disabled Status of the authenticated User.
Therefor the OwncloudUserDetails
Object will be included into the OwncloudAuthentication
Object and will be returned by calling getPrincipal()
.
Because Owncloud only serves the Enabled/Disabled Status of the User the following Method will always return true
:
-
isAccountNonExpired()
-
isAccountNonLocked()
-
isCredentialsNonExpired()
Beside the normal Attributes of the Spring Security UserDetails
Object the OwncloudUserDetails
Object provides the following, additional Fields:
-
getDisplayName()
… The full Name of the User -
getEmail()
… The Email of the User -
getGroups()
… A List of Groups the User is a Member of
9. OwncloudUserService
When you are authenticated by the Owncloud AuthenticationProvider
you can use this Service simply by @Autowire
it to your Bean.
For more Details about the Owncloud REST-Calls please look at the Owncloud User provisioning API.
The following Methods will be available:
Method | Owncloud REST Call | Description | ||
---|---|---|---|---|
|
|
All Users |
||
|
|
All Users whose Display Name matches the Search criteria |
||
|
|
Information about one User
|
||
|
additional (when creating a new User): modifying User:
when Groups will be modified:
|
|
||
|
|
Removes a User from Owncloud
|
9.1. creating a new User
If you want to create a new User you create a new Instance of OwncloudModificationUser
OwncloudModificationUser newUser = OwncloudModificationUser.builder()
.username("username")
.password("s3cr3t")
.displayName("Display Name of the new User")
.email("user@example.com")
.group("group1")
.group("group2")
.build();
OwncloudUserDetails createdUser =
owncloudUserModificationService.saveUser(newUser);
9.2. modifying a User
If you want to modify the Information about a User this User has to be read just before by
OwncloudUserService.findOne(String username)
. With the OwncloudUserDetails
Object
in Hands you can create a new OwncloudModificationUser
.
owncloudUserService.findOne("user1")
.map(OwncloudModificationUser::of)
.map(modificationUser -> {
modificationUser.setDisplayName("new Display Name of the User");
return modificationUser;
})
.ifPresent(owncloudUserService::save);
10. OwncloudGroupService
When you are authenticated by the Owncloud AuthenticationProvider
you can use this Service simply by @Autowire
it to your Bean.
For more Details about the Owncloud REST-Calls please look at the Owncloud User provisioning API.
The following Methods will be available:
Method | Owncloud REST-Call | Description | ||
---|---|---|---|---|
|
|
All Groups |
||
|
|
All Groups whose Name matches the Search criteria |
||
|
|
All Users associated to the Group |
||
|
|
All Groups associated to the User |
||
|
|
Create a new Group |
||
|
|
Removes a Group from Owncloud
|
11. enable/disable User Modifications
Because Modifications by OwncloudUserService
(save
, delete
) or by OwncloudGroupService
(create
, delete
)
need administrative Privileges of the User there is the Danger, that the Application will remove Users and/or Groups unintentionally.
To protect the Usage of OwncloudUserService
and OwncloudGroupService
can be restricted.
This Restriction is disabled by default.
To deny Modifications by OwncloudUserService
and OwncloudGroupService
you can set the following Property
owncloud.enable-modifications=false
12. Resource Service
One of the main Aspects of Owncloud is the Usage of a centralized WebDAV File Store.
By using the OwncloudResourceService
you can interact with this WebDAV-based File Store.
Simply by @Autowire
the OwncloudResourceService
you can use the following Methods:
Method | REST-Call | Description | ||
---|---|---|---|---|
|
|
Get all Information about Files and/or Directories of the currently authenticated Users Root Directory. |
||
|
|
Get all Information about Files and/or Directories of the given URI. |
||
|
|
Find a File or Directory by its URI relative to the Root Directory of the currently authenticated User. |
||
|
|
Create a Directory relative to the Root Directory of the currently authenticated User |
||
|
|
Delete a File or Directory referenced by the
|
||
|
|
get an |
||
|
|
get an |
||
|
|
create a new File and get an |
||
|
|
get the Quota of the actual authenticated User |
12.1. OwncloudResource
A OwncloudResource
is an abstract Representation of a Resource on the Owncloud.
This Resource can either be a File or a Directory.
The following Information is available about this Resource:
Information | Datatype |
---|---|
href |
|
name |
|
lastModifiedAt |
|
mediaType |
|
eTag |
|
In the case of a File Representation a OwncloudFileResource
as a Subclass of
OwncloudResource
will be instantiated. This OwncloudFileResource
has the
following additional Information:
Information | Datatype |
---|---|
contentLength |
|
12.2. from OwncloudResource to OwncloudFileResource
The Methods listRoot()
and list(URI relativeTo)
both return a List of OwncloudResource
because the Content of a Directory can either be Files or another Directories (Subdirectories).
In the case of a Directory the MediaType
of the OwncloudResource
is set to httpd/unix-directory
.
If you have a File (when MediaType
of OwncloudResource
is not httpd/unix-directory
) you can
convert the OwncloudResource
to a OwncloudFileResource
. Only with the OwncloudFileResource
you can read or write the Content of this File.
Optional<OwncloudFileResource> fileResource =
resourceService.find(uri)
.filter(OwncloudUtils::isNotDirectory)
.map(OwncloudUtils:toOwncloudFileResource);
12.3. relative Super Directory
When you call list(URI relativeTo)
you will get a List of Files/Directories
of the given URI relative to the User Root. OwncloudResourceService
will
give you 2 additional Entries: . (actual Directory) and .. (Parent Directory)
If you don’t want a Reference to the Parent Directory you can set
the Configuration Property owncloud.resource-service.add-relative-down-path
to
false
. (Default is: true
).
After setting this Configuration to false
no additional Entriy ..
with
a Reference to the Parent Directory will be added to the Result of
list(URI relativeTo)
.
By letting this Configuration Property to its Default Value of true
the relative
Link to the Super Directory will be added. The only Exception is the Root-Directory
of the User because you can’t navigate below to the Root-Directory.
12.4. Local Resource Service
As with the OwncloudUserService
and the OwncloudGroupService
you can route the OwncloudResource
to use a local Storage instead of
a remote Owncloud Instance. You can use the local Storage for Unit-
and/or Integration-Tests.
Warning
|
Don’t use the local Storage of the OwncloudResource
to build your own WebDAV Storage. This is not the intent of this Project
and the Developers will not take any responsibility for lost Data.
|
You use the local Storage by setting the local Implementation and a Path
to the Root Directory for all Users defined by owncloud.xml
.
owncloud:
location: classpath:/owncloud.xml
resource-service:
location: /path/to/files
A Subdirectory will be created for every User of the owncloud.xml
at the
first Time he/she uses any Method of OwncloudResourceService
.
For Instance: if User jane
uses any Method of OwncloudResourceService
a Directory /path/to/files/jane
will be created.
12.5. eTag
The Owncloud calculates an eTag for every Resource. This eTag will be used by the Owncloud Client to sync changed Files/Directories.
The Local Storage of OwncloudResourceService
has a similar eTag Calculation
based on a MessageDigest Algorithm. At the Moment only MD5 will be used.
The Checksum of a File will be calculated by its Content. The Checksum of a Directory will be calculated by recursevly concatinating the Checksum of all Files within this Directory and its Subdirectories.
Everytime the Content of a File changes (either by
OwncloudResourceService.getOutputStream
or when any other Process outside
of the Spring-Boot Application changes the Content of the File) the Checksum
will be recalculated.
For better Performance the Checksums will be cached. On Application Startup
the Checksum of all Files and Directories under the Path referenced by the Property
owncloud.resource-service.location
will be calculated and written to a Java Map.
This will take some time and the Application Startup has been locked until the Calculation has been finished. To keep Unit-Tests fast keep the Number and Size of Files small.
12.6. piped Streams
The API of OwncloudResourceService
is simple. Because of its simplicity in the
Background there are some challenges because of deferred Read/Write Operations
(when using the REST Backend).
12.6.1. piped OutputStream
So the Write-Process (OwncloudResourceService.getOutputStream()
) never will be
called directly on the Files. Instead you (Developer who uses the OwncloudResourceService
)
will get one end of a Pipe, the PipedOutputStream
. With this OutputStream you can
handle all your Streaming.
In the Background there has been started a new Thread who keeps the other end of
the Pipe, the PipedInputStream
. All Data written to the PipedOutputStream
will
be read by the PipedInputStream
. This Background Process handles the Communication
with the deferred Owncloud System. If there are some Errors during the I/O Process
(i.E. the Owncloud will be shutdown or network problems) the Background Process cancels
the Transfer and throws an OwncloudException
(either when writing or on close of
the PipedOutputStream
).
Also the local Implementation of OwncloudResourceService.getOutputStream()
uses this
Background Process to first write to a temporary File. Only on close()
the temporary
File will be moved to the real Position. The temporary File will be created on the
temporary Path-Location (via Files.createTempFile()
). The Prefix of this temporary
File can be customized via the Configuration Property
owncloud.resource-service.piped-stream-temporary-file-prefix
.
The Default is: owncloud
owncloud:
location: classpath:/owncloud.xml
resource-service:
location: /path/to/files
piped-stream-temporary-file-prefix: owncloud
12.6.2. piped InputStream
Also the REST-Backend of OwncloudResourceService.getInputStream()
uses the piped Streams to handle the deferred Communication to the
Owncloud.
So if you call OwncloudResourceService.getInputStream()
then you will
get a PipedInputStream
. This Pipe is connected to a Background Thread
which keeps the PipedOutputStream
. If there are any Errors during the
deferred Read then an OwncloudException
will be thrown.
The local Implementation of OwncloudResourceService.getInputStream()
on the other Hand doesn’t use this Synchronization Mechanism. Instead
you will get a FileInputStream
with which you can read the Data directly.
Please keep this in mind:
Note
|
the REST-Implementation of OwncloudResourceService.getInputStream()
uses the piped Stream Synchronization Mechanism to handle deferred Exceptions.
The local Implementation returns a FileInputStream to the File without the
synchronization Mechanism.
|
12.6.3. Synchronization Buffer
By the Configuration Parameter owncloud.resource-service.piped-stream-buffer-size
you can manage the Bytes which will be read/write by the piped Stream. The Value is
in Bytes. The Default is 8K (8.192) Bytes.
owncloud:
location: classpath:/owncloud.xml
resource-service:
location: /path/to/files
piped-stream-buffer-size: 8192
12.6.4. Exceptions during Background Synchronization
The Background-Thread will be automatically created (and also destroyed) by
the owncloud-spring-boot-starter. It will be created if you call
OwncloudResourceService.getInputStream()
(only REST-Backend) or
OwncloudResourceService.getOutputStream()
(REST- and local Backend).
It will be closed if you call close()
on either the InputStream
or the
OutputStream
Object.
On any Error during the Background Communication the Background-Thread throws
an Instance of OwncloudException
and logs the Exception to SLF4J.
The Log-Level of this uncaught Exception can be handled by the Configuration
Parameter owncloud.resource-service.piped-stream-uncaught-exception-log-level
Any valid SLF4J LogLevel can be served. The Default is LogLevel.ERROR
.
12.7. Sardine Cache (only REST Backend)
Because the WebDAV Protocol enhances the HTTP Protocol by some Methods (PROPFIND
, MKCOL
, …)
these Methods are not implemented by the Spring RestTemplate.
But Sardine is an excellent WebDAV Implementation for Java.
Therefor we use Sardine for these HTTP Enhancements.
To keep the Time as short as possible for consecutive WebDAV Operations the Sardine Session of the authenticated User will be cached and reused as long as the User keep the WebDAV Requests active.
This happens by using a Google Guava Cache. The Properties for this Cache can be maintained by Configuration Properties:
owncloud:
location: classpath:/owncloud.xml
resource-service:
sardine-cache:
concurrency-level: 6
expire-after-access: 5
expire-after-access-time-unit: MINUTES
For a full List of the Configuration Properties look at Configuration (available for: REST)
13. Logging
This Project uses SLF4J to produce the Logs.
You can disable the Logging by setting the Log-Level of the Package software.coolstuff.springframework.owncloud
to off
.
logging.level.software.coolstuff.springframework.owncloud=off
As an alternative you can set the Log-Level to trace
if you would like to get all Rest-Requests:
logging.level.software.coolstuff.springframework.owncloud=trace
14. Contributions
You can fork this Project on Github and create a Pull Request.
15. License
This Project is licensed under the GPL 3.0 License.