You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by ss...@apache.org on 2014/01/09 18:54:54 UTC

[2/2] git commit: implement a LDCache backend using Infinispan

implement a LDCache backend using Infinispan


Project: http://git-wip-us.apache.org/repos/asf/marmotta/repo
Commit: http://git-wip-us.apache.org/repos/asf/marmotta/commit/4aa89b0b
Tree: http://git-wip-us.apache.org/repos/asf/marmotta/tree/4aa89b0b
Diff: http://git-wip-us.apache.org/repos/asf/marmotta/diff/4aa89b0b

Branch: refs/heads/develop
Commit: 4aa89b0b1cdb1c4ca82c928a19941b8864e71636
Parents: aaf499a
Author: Sebastian Schaffert <ss...@apache.org>
Authored: Thu Jan 9 18:54:47 2014 +0100
Committer: Sebastian Schaffert <ss...@apache.org>
Committed: Thu Jan 9 18:54:47 2014 +0100

----------------------------------------------------------------------
 .../marmotta/ldcache/model/CacheEntry.java      |   3 +-
 .../ldcache/ldcache-backend-infinispan/pom.xml  | 136 ++++++++
 .../infinispan/LDCachingInfinispanBackend.java  | 237 ++++++++++++++
 ...LDCachingInfinispanRepositoryConnection.java | 130 ++++++++
 .../src/main/resources/jgroups-ldcache.xml      |  91 ++++++
 .../infinispan/test/LDCacheInfinispanTest.java  | 135 ++++++++
 .../services/test/dummy/DummyEndpoint.java      |  29 ++
 .../services/test/dummy/DummyProvider.java      |  82 +++++
 .../ldcache/services/test/dummy/DummyTest.java  |  82 +++++
 ...ache.marmotta.ldclient.api.endpoint.Endpoint |   1 +
 ....marmotta.ldclient.api.provider.DataProvider |   1 +
 .../src/test/resources/logback.xml              |  27 ++
 .../ldcache/services/test/dummy/resource1.ttl   |  21 ++
 .../ldcache/services/test/dummy/resource2.ttl   |  20 ++
 .../ldcache/services/test/dummy/resource3.ttl   |  20 ++
 libraries/ldcache/ldcache-backend-kiwi/pom.xml  |  10 +
 .../ldcache/services/test/LDCacheKiWiTest.java  | 307 +++++++++++++++++++
 .../services/test/dummy/DummyEndpoint.java      |  29 ++
 .../services/test/dummy/DummyProvider.java      |  82 +++++
 .../ldcache/services/test/dummy/DummyTest.java  |  82 +++++
 ...ache.marmotta.ldclient.api.endpoint.Endpoint |   1 +
 ....marmotta.ldclient.api.provider.DataProvider |   1 +
 .../ldcache/services/test/dummy/resource1.ttl   |  21 ++
 .../ldcache/services/test/dummy/resource2.ttl   |  20 ++
 .../ldcache/services/test/dummy/resource3.ttl   |  20 ++
 libraries/ldcache/ldcache-core/pom.xml          |  26 --
 .../ldcache/services/test/LDCacheKiWiTest.java  | 307 -------------------
 .../services/test/dummy/DummyEndpoint.java      |  29 --
 .../services/test/dummy/DummyProvider.java      |  82 -----
 .../ldcache/services/test/dummy/DummyTest.java  |  82 -----
 ...ache.marmotta.ldclient.api.endpoint.Endpoint |   1 -
 ....marmotta.ldclient.api.provider.DataProvider |   1 -
 .../ldcache/services/test/dummy/resource1.ttl   |  21 --
 .../ldcache/services/test/dummy/resource2.ttl   |  20 --
 .../ldcache/services/test/dummy/resource3.ttl   |  20 --
 libraries/ldcache/pom.xml                       |   1 +
 parent/pom.xml                                  |   5 +
 37 files changed, 1593 insertions(+), 590 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-api/src/main/java/org/apache/marmotta/ldcache/model/CacheEntry.java
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-api/src/main/java/org/apache/marmotta/ldcache/model/CacheEntry.java b/libraries/ldcache/ldcache-api/src/main/java/org/apache/marmotta/ldcache/model/CacheEntry.java
index 4c7db25..e194586 100644
--- a/libraries/ldcache/ldcache-api/src/main/java/org/apache/marmotta/ldcache/model/CacheEntry.java
+++ b/libraries/ldcache/ldcache-api/src/main/java/org/apache/marmotta/ldcache/model/CacheEntry.java
@@ -19,6 +19,7 @@ package org.apache.marmotta.ldcache.model;
 
 import org.openrdf.model.URI;
 
+import java.io.Serializable;
 import java.util.Date;
 
 /**
@@ -27,7 +28,7 @@ import java.util.Date;
  * <p/>
  * User: Sebastian Schaffert
  */
-public class CacheEntry {
+public class CacheEntry implements Serializable {
 
     /**
      * The URI resource managed by this cache entry.

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-infinispan/pom.xml
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-infinispan/pom.xml b/libraries/ldcache/ldcache-backend-infinispan/pom.xml
new file mode 100644
index 0000000..654f470
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-infinispan/pom.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.marmotta</groupId>
+        <artifactId>marmotta-parent</artifactId>
+        <version>3.2.0-SNAPSHOT</version>
+        <relativePath>../../../parent</relativePath>
+    </parent>
+
+    <artifactId>ldcache-backend-infinispan</artifactId>
+    <name>LDCache Backend: Infinispan</name>
+
+    <description>
+        Linked Data Caching Backend based on the Infinispan Data Grid. Will represent cache entries and triples
+        in a distributed data grid in memory with dynamic cluster balancing.
+    </description>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.marmotta</groupId>
+            <artifactId>ldcache-api</artifactId>
+        </dependency>
+
+        <!-- Logging -->
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>log4j-over-slf4j</artifactId>
+        </dependency>
+
+
+        <!-- Caching  -->
+        <dependency>
+            <groupId>org.infinispan</groupId>
+            <artifactId>infinispan-core</artifactId>
+        </dependency>
+
+        <!-- Sesame dependencies -->
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-model</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-repository-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-repository-sail</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-sail-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-sail-memory</artifactId>
+        </dependency>
+
+
+
+        <!-- Testing -->
+        <dependency>
+            <artifactId>junit</artifactId>
+            <groupId>junit</groupId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <artifactId>hamcrest-core</artifactId>
+            <groupId>org.hamcrest</groupId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <artifactId>hamcrest-library</artifactId>
+            <groupId>org.hamcrest</groupId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.marmotta</groupId>
+            <artifactId>ldcache-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-rio-turtle</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+
+    </dependencies>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-infinispan/src/main/java/org/apache/marmotta/ldcache/backend/infinispan/LDCachingInfinispanBackend.java
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-infinispan/src/main/java/org/apache/marmotta/ldcache/backend/infinispan/LDCachingInfinispanBackend.java b/libraries/ldcache/ldcache-backend-infinispan/src/main/java/org/apache/marmotta/ldcache/backend/infinispan/LDCachingInfinispanBackend.java
new file mode 100644
index 0000000..686d11a
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-infinispan/src/main/java/org/apache/marmotta/ldcache/backend/infinispan/LDCachingInfinispanBackend.java
@@ -0,0 +1,237 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.ldcache.backend.infinispan;
+
+import info.aduna.iteration.CloseableIteration;
+import info.aduna.iteration.CloseableIteratorIteration;
+import info.aduna.iteration.EmptyIteration;
+import org.apache.marmotta.ldcache.api.LDCachingBackend;
+import org.apache.marmotta.ldcache.api.LDCachingConnection;
+import org.apache.marmotta.ldcache.backend.infinispan.repository.LDCachingInfinispanRepositoryConnection;
+import org.apache.marmotta.ldcache.model.CacheEntry;
+import org.infinispan.Cache;
+import org.infinispan.configuration.cache.CacheMode;
+import org.infinispan.configuration.cache.Configuration;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.configuration.global.GlobalConfiguration;
+import org.infinispan.configuration.global.GlobalConfigurationBuilder;
+import org.infinispan.context.Flag;
+import org.infinispan.distribution.ch.SyncConsistentHashFactory;
+import org.infinispan.eviction.EvictionStrategy;
+import org.infinispan.manager.DefaultCacheManager;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.openrdf.model.Model;
+import org.openrdf.repository.RepositoryException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert (sschaffert@apache.org)
+ */
+public class LDCachingInfinispanBackend implements LDCachingBackend {
+
+    public static final String LDCACHE_ENTRY_CACHE = "ldcache-entry-cache";
+    public static final String LDCACHE_TRIPLE_CACHE = "ldcache-triple-cache";
+    private static Logger log = LoggerFactory.getLogger(LDCachingInfinispanBackend.class);
+
+    private EmbeddedCacheManager cacheManager;
+
+    private GlobalConfiguration globalConfiguration;
+
+    private Configuration defaultConfiguration;
+
+    private boolean clustered;
+
+    private Cache<String,CacheEntry> entryCache;
+    private Cache<String,Model>      tripleCache;
+
+    /**
+     * Create a non-clustered instance of the infinispan cache.
+     */
+    public LDCachingInfinispanBackend() {
+        globalConfiguration = new GlobalConfigurationBuilder()
+                .classLoader(LDCachingInfinispanBackend.class.getClassLoader())
+                .globalJmxStatistics()
+                    .jmxDomain("org.apache.marmotta.ldcache")
+                    .allowDuplicateDomains(true)
+                .build();
+
+        defaultConfiguration = new ConfigurationBuilder()
+                .clustering()
+                    .cacheMode(CacheMode.LOCAL)
+                .eviction()
+                    .strategy(EvictionStrategy.LIRS)
+                    .maxEntries(100000)
+                .expiration()
+                    .lifespan(7, TimeUnit.DAYS)
+                    .maxIdle(1, TimeUnit.DAYS)
+                .build();
+
+        clustered = false;
+
+    }
+
+    /**
+     * Create a clustered instane of the infinispan cache backend using the provided cluster and machine name
+     * @param clusterName
+     * @param machineName
+     */
+    public LDCachingInfinispanBackend(String clusterName, String machineName) {
+        globalConfiguration = new GlobalConfigurationBuilder()
+                .classLoader(LDCachingInfinispanBackend.class.getClassLoader())
+                .transport()
+                    .defaultTransport()
+                    .clusterName(clusterName)
+                    .machineId(machineName)
+                    .addProperty("configurationFile", "jgroups-kiwi.xml")
+                .globalJmxStatistics()
+                    .jmxDomain("org.apache.marmotta.ldcache")
+                    .allowDuplicateDomains(true)
+                .build();
+
+
+
+        defaultConfiguration = new ConfigurationBuilder()
+                .clustering()
+                    .cacheMode(CacheMode.DIST_ASYNC)
+                        .async()
+                        .asyncMarshalling()
+                    .l1()
+                        .lifespan(5, TimeUnit.MINUTES)
+                    .hash()
+                        .numOwners(2)
+                        .numSegments(40)
+                        .consistentHashFactory(new SyncConsistentHashFactory())
+                .stateTransfer()
+                    .fetchInMemoryState(false)
+                .eviction()
+                    .strategy(EvictionStrategy.LIRS)
+                    .maxEntries(100000)
+                .expiration()
+                    .lifespan(7, TimeUnit.DAYS)
+                    .maxIdle(1, TimeUnit.DAYS)
+                .build();
+
+
+        clustered = true;
+
+
+    }
+
+
+    public Cache<String,CacheEntry> getEntryCache() {
+        if(entryCache == null) {
+            cacheManager.defineConfiguration(LDCACHE_ENTRY_CACHE, defaultConfiguration);
+
+            entryCache = cacheManager.<String,CacheEntry>getCache(LDCACHE_ENTRY_CACHE).getAdvancedCache().withFlags(Flag.SKIP_LOCKING, Flag.SKIP_CACHE_LOAD, Flag.SKIP_REMOTE_LOOKUP);
+        }
+
+        return entryCache;
+
+    }
+
+    public Cache<String,Model> getTripleCache() {
+        if(tripleCache == null) {
+            cacheManager.defineConfiguration(LDCACHE_TRIPLE_CACHE, defaultConfiguration);
+
+            tripleCache = cacheManager.<String,Model>getCache(LDCACHE_TRIPLE_CACHE).getAdvancedCache().withFlags(Flag.SKIP_LOCKING, Flag.SKIP_CACHE_LOAD, Flag.SKIP_REMOTE_LOOKUP);
+        }
+
+        return tripleCache;
+
+    }
+
+    /**
+     * Return a repository connection that can be used for caching. The LDCache will first remove all statements for
+     * the newly cached resources and then add retrieved statements as-is to this connection and properly commit and
+     * close it after use.
+     * <p/>
+     * Note that in case the statements should be rewritten this method must take care of providing the proper
+     * connection, e.g. by using a ContextAwareRepositoryConnection to add a context to all statements when adding them.
+     *
+     * @param resource the resource that will be cached
+     * @return a repository connection that can be used for storing retrieved triples for caching
+     */
+    @Override
+    public LDCachingConnection getCacheConnection(String resource) throws RepositoryException {
+        return new LDCachingInfinispanRepositoryConnection(this, resource);
+    }
+
+    /**
+     * Return an iterator over all expired cache entries (can e.g. be used for refreshing).
+     *
+     * @return
+     */
+    @Override
+    public CloseableIteration<CacheEntry, RepositoryException> listExpiredEntries() throws RepositoryException {
+        return new EmptyIteration<>();  // Infinispan does not allow listing expired entries
+    }
+
+    /**
+     * Return an iterator over all cache entries (can e.g. be used for refreshing or expiring).
+     *
+     * @return
+     */
+    @Override
+    public CloseableIteration<CacheEntry, RepositoryException> listCacheEntries() throws RepositoryException {
+        return new CloseableIteratorIteration<>(getEntryCache().values().iterator());
+    }
+
+    /**
+     * Return true in case the resource is a cached resource.
+     *
+     * @param resource the URI of the resource to check
+     * @return true in case the resource is a cached resource
+     */
+    @Override
+    public boolean isCached(String resource) throws RepositoryException {
+        return getEntryCache().containsKey(resource);
+    }
+
+    /**
+     * Carry out any initialization tasks that might be necessary
+     */
+    @Override
+    public void initialize() {
+        cacheManager = new DefaultCacheManager(globalConfiguration, defaultConfiguration, true);
+
+        getEntryCache();
+        getTripleCache();
+
+        log.info("initialised cache manager ({})", globalConfiguration.isClustered() ? "cluster name: "+globalConfiguration.transport().clusterName() : "single host");
+
+    }
+
+    /**
+     * Shutdown the backend and free all runtime resources.
+     */
+    @Override
+    public void shutdown() {
+        log.warn("shutting down cache manager ...");
+        if(cacheManager.getTransport() != null) {
+            log.info("... shutting down transport ...");
+            cacheManager.getTransport().stop();
+        }
+        log.info("... shutting down main component ...");
+        cacheManager.stop();
+        log.info("... done!");
+    }
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-infinispan/src/main/java/org/apache/marmotta/ldcache/backend/infinispan/repository/LDCachingInfinispanRepositoryConnection.java
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-infinispan/src/main/java/org/apache/marmotta/ldcache/backend/infinispan/repository/LDCachingInfinispanRepositoryConnection.java b/libraries/ldcache/ldcache-backend-infinispan/src/main/java/org/apache/marmotta/ldcache/backend/infinispan/repository/LDCachingInfinispanRepositoryConnection.java
new file mode 100644
index 0000000..57f8289
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-infinispan/src/main/java/org/apache/marmotta/ldcache/backend/infinispan/repository/LDCachingInfinispanRepositoryConnection.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.marmotta.ldcache.backend.infinispan.repository;
+
+import org.apache.marmotta.ldcache.api.LDCachingConnection;
+import org.apache.marmotta.ldcache.backend.infinispan.LDCachingInfinispanBackend;
+import org.apache.marmotta.ldcache.model.CacheEntry;
+import org.openrdf.model.Model;
+import org.openrdf.model.Statement;
+import org.openrdf.model.URI;
+import org.openrdf.model.impl.TreeModel;
+import org.openrdf.repository.Repository;
+import org.openrdf.repository.RepositoryConnection;
+import org.openrdf.repository.RepositoryException;
+import org.openrdf.repository.RepositoryResult;
+import org.openrdf.repository.base.RepositoryConnectionWrapper;
+import org.openrdf.repository.sail.SailRepository;
+import org.openrdf.sail.memory.MemoryStore;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Add file description here!
+ *
+ * @author Sebastian Schaffert (sschaffert@apache.org)
+ */
+public class LDCachingInfinispanRepositoryConnection extends RepositoryConnectionWrapper implements LDCachingConnection {
+
+    private LDCachingInfinispanBackend backend;
+
+    private String resource;
+
+    public LDCachingInfinispanRepositoryConnection(LDCachingInfinispanBackend backend, String resource) throws RepositoryException {
+        super(getModelRepository(backend.getTripleCache().get(resource)));
+        setDelegate(getRepository().getConnection());
+        this.backend = backend;
+        this.resource = resource;
+    }
+
+
+    private static Repository getModelRepository(Model model) throws RepositoryException {
+        Repository repository = new SailRepository(new MemoryStore());
+        repository.initialize();
+
+        RepositoryConnection con = repository.getConnection();
+        try {
+            con.begin();
+
+            if(model != null) {
+                con.add(model);
+            }
+
+            con.commit();
+        } catch(RepositoryException ex) {
+            con.rollback();
+        } finally {
+            con.close();
+        }
+
+        return repository;
+    }
+
+
+    /**
+     * Get the cache entry for the passed resource, if any. Returns null in case there is no cache entry.
+     *
+     * @param resource the resource to look for
+     * @return the cache entry for the resource, or null if the resource has never been cached or is expired
+     */
+    @Override
+    public CacheEntry getCacheEntry(URI resource) throws RepositoryException {
+        return backend.getEntryCache().get(resource.stringValue());
+    }
+
+    /**
+     * Store a cache entry for the passed resource in the backend. Depending on the backend, this can be a
+     * persistent storage or an in-memory storage.
+     *
+     * @param resource
+     * @param entry
+     */
+    @Override
+    public void addCacheEntry(URI resource, CacheEntry entry) throws RepositoryException {
+        backend.getEntryCache().putAsync(resource.stringValue(),entry,entry.getExpiryDate().getTime() - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
+
+        Model model = new TreeModel();
+
+        RepositoryResult<Statement> triples = getStatements(resource,null,null,true);
+        try {
+            while(triples.hasNext()) {
+                model.add(triples.next());
+            }
+        } finally {
+            triples.close();
+        }
+
+        backend.getTripleCache().putAsync(resource.stringValue(),model,entry.getExpiryDate().getTime() - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
+    }
+
+    /**
+     * Remove the currently stored cache entry for the passed resource from the backend.
+     *
+     * @param resource
+     */
+    @Override
+    public void removeCacheEntry(URI resource) throws RepositoryException {
+        backend.getEntryCache().removeAsync(resource.stringValue());
+        backend.getTripleCache().removeAsync(resource.stringValue());
+    }
+
+    @Override
+    public void close() throws RepositoryException {
+        super.close();
+    }
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-infinispan/src/main/resources/jgroups-ldcache.xml
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-infinispan/src/main/resources/jgroups-ldcache.xml b/libraries/ldcache/ldcache-backend-infinispan/src/main/resources/jgroups-ldcache.xml
new file mode 100644
index 0000000..1b1b0bd
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-infinispan/src/main/resources/jgroups-ldcache.xml
@@ -0,0 +1,91 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<config xmlns="urn:org:jgroups"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="urn:org:jgroups http://www.jgroups.org/schema/JGroups-3.4.xsd">
+   <UDP
+         mcast_addr="${jgroups.udp.mcast_addr:228.6.7.8}"
+         mcast_port="${jgroups.udp.mcast_port:46656}"
+         tos="8"
+         ucast_recv_buf_size="20m"
+         ucast_send_buf_size="640k"
+         mcast_recv_buf_size="25m"
+         mcast_send_buf_size="640k"
+         loopback="true"
+         max_bundle_size="31k"
+         ip_ttl="${jgroups.udp.ip_ttl:2}"
+         enable_diagnostics="false"
+         bundler_type="old"
+
+         thread_naming_pattern="pl"
+
+         thread_pool.enabled="true"
+         thread_pool.min_threads="2"
+         thread_pool.max_threads="30"
+         thread_pool.keep_alive_time="60000"
+         thread_pool.queue_enabled="true"
+         thread_pool.queue_max_size="100"
+         thread_pool.rejection_policy="Discard"
+
+         oob_thread_pool.enabled="true"
+         oob_thread_pool.min_threads="2"
+         oob_thread_pool.max_threads="30"
+         oob_thread_pool.keep_alive_time="60000"
+         oob_thread_pool.queue_enabled="false"
+         oob_thread_pool.queue_max_size="100"
+         oob_thread_pool.rejection_policy="Discard"
+
+         internal_thread_pool.enabled="true"
+         internal_thread_pool.min_threads="1"
+         internal_thread_pool.max_threads="10"
+         internal_thread_pool.keep_alive_time="60000"
+         internal_thread_pool.queue_enabled="true"
+         internal_thread_pool.queue_max_size="100"
+         internal_thread_pool.rejection_policy="Discard"
+         />
+
+   <PING timeout="3000" num_initial_members="3"/>
+   <MERGE2 max_interval="30000" min_interval="10000"/>
+
+   <FD_SOCK/>
+   <FD_ALL timeout="30000" interval="3000"/>
+   <VERIFY_SUSPECT timeout="1500" num_msgs="5"/>
+
+   <pbcast.NAKACK2
+                    xmit_interval="1000"
+                    xmit_table_num_rows="100"
+                    xmit_table_msgs_per_row="10000"
+                    xmit_table_max_compaction_time="10000"
+                    max_msg_batch_size="100"/>
+   <UNICAST3
+              xmit_interval="500"
+              xmit_table_num_rows="20"
+              xmit_table_msgs_per_row="10000"
+              xmit_table_max_compaction_time="10000"
+              max_msg_batch_size="100"
+              conn_expiry_timeout="0"/>
+
+   <pbcast.STABLE stability_delay="500" desired_avg_gossip="5000" max_bytes="1m"/>
+   <pbcast.GMS print_local_addr="false" join_timeout="3000" view_bundling="true"/>
+   <tom.TOA/> <!-- the TOA is only needed for total order transactions-->
+
+   <UFC max_credits="2m" min_threshold="0.40"/>
+   <MFC max_credits="2m" min_threshold="0.40"/>
+   <FRAG2 frag_size="30k"  />
+   <RSVP timeout="60000" resend_interval="500" ack_on_delivery="false" />
+</config>

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-infinispan/src/test/java/org/apache/marmotta/ldcache/infinispan/test/LDCacheInfinispanTest.java
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-infinispan/src/test/java/org/apache/marmotta/ldcache/infinispan/test/LDCacheInfinispanTest.java b/libraries/ldcache/ldcache-backend-infinispan/src/test/java/org/apache/marmotta/ldcache/infinispan/test/LDCacheInfinispanTest.java
new file mode 100644
index 0000000..f26abf6
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-infinispan/src/test/java/org/apache/marmotta/ldcache/infinispan/test/LDCacheInfinispanTest.java
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.ldcache.infinispan.test;
+
+import info.aduna.iteration.CloseableIteration;
+import org.apache.marmotta.ldcache.backend.infinispan.LDCachingInfinispanBackend;
+import org.apache.marmotta.ldcache.model.CacheConfiguration;
+import org.apache.marmotta.ldcache.services.LDCache;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.openrdf.model.ValueFactory;
+import org.openrdf.model.impl.ValueFactoryImpl;
+import org.openrdf.repository.RepositoryConnection;
+import org.openrdf.repository.RepositoryException;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class LDCacheInfinispanTest {
+
+
+    private LDCachingInfinispanBackend backend;
+
+    private LDCache ldcache;
+
+    private ValueFactory valueFactory;
+
+    @Before
+    public void initCache() throws RepositoryException {
+        backend = new LDCachingInfinispanBackend();
+        backend.initialize();
+
+        ldcache = new LDCache(new CacheConfiguration(),backend);
+
+        valueFactory = new ValueFactoryImpl();
+    }
+
+    @After
+    public void shutdownCache() throws RepositoryException, SQLException {
+        backend.shutdown();
+    }
+
+
+    /**
+     * Test retrieving and caching some resources (provided by DummyProvider).
+     */
+    @Test
+    public void testCacheResources() throws Exception {
+        String uri1 = "http://localhost/resource1";
+        String uri2 = "http://localhost/resource2";
+        String uri3 = "http://localhost/resource3";
+
+        ldcache.refreshResource(valueFactory.createURI(uri1),false);
+
+        Assert.assertEquals(1, asList(ldcache.listCacheEntries()).size());
+
+        RepositoryConnection con1 = ldcache.getCacheConnection(uri1);
+        try {
+            con1.begin();
+            Assert.assertEquals(3, asList(con1.getStatements(con1.getValueFactory().createURI(uri1), null, null, false)).size());
+            con1.commit();
+        } finally {
+            con1.close();
+        }
+
+        ldcache.refreshResource(valueFactory.createURI(uri2), false);
+
+        Assert.assertEquals(2, asList(ldcache.listCacheEntries()).size());
+
+        RepositoryConnection con2 = ldcache.getCacheConnection(uri2);
+        try {
+            con2.begin();
+            Assert.assertEquals(2, asList(con2.getStatements(con2.getValueFactory().createURI(uri2), null, null, false)).size());
+            con2.commit();
+        } finally {
+            con2.close();
+        }
+
+        ldcache.refreshResource(valueFactory.createURI(uri3), false);
+
+        Assert.assertEquals(3,asList(ldcache.listCacheEntries()).size());
+
+        RepositoryConnection con3 = ldcache.getCacheConnection(uri3);
+        try {
+            con3.begin();
+            Assert.assertEquals(2, asList(con3.getStatements(con3.getValueFactory().createURI(uri3), null, null, false)).size());
+            con3.commit();
+        } finally {
+            con3.close();
+        }
+    }
+
+
+    /*
+
+    /**
+     * Workaround for https://openrdf.atlassian.net/browse/SES-1702 in Sesame 2.7.0-beta1
+     * @param <E>
+     * @return
+     */
+    public static <E,X extends Exception> List<E> asList(CloseableIteration<E,X> result) throws RepositoryException {
+        ArrayList<E> collection = new ArrayList<E>();
+        try {
+            try {
+                while (result.hasNext()) {
+                    collection.add(result.next());
+                }
+
+                return collection;
+            } finally {
+                result.close();
+            }
+        } catch(Throwable ex) {
+            throw new RepositoryException(ex);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-infinispan/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyEndpoint.java
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-infinispan/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyEndpoint.java b/libraries/ldcache/ldcache-backend-infinispan/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyEndpoint.java
new file mode 100644
index 0000000..1289776
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-infinispan/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyEndpoint.java
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.ldcache.services.test.dummy;
+
+import org.apache.marmotta.ldclient.api.endpoint.Endpoint;
+
+public class DummyEndpoint extends Endpoint {
+	
+	public DummyEndpoint() {
+		super("Dummy", "Dummy", "^http://localhost", null, 86400l);
+		setPriority(PRIORITY_HIGH);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-infinispan/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyProvider.java
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-infinispan/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyProvider.java b/libraries/ldcache/ldcache-backend-infinispan/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyProvider.java
new file mode 100644
index 0000000..4b6f92a
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-infinispan/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyProvider.java
@@ -0,0 +1,82 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.ldcache.services.test.dummy;
+
+import org.apache.marmotta.ldclient.api.endpoint.Endpoint;
+import org.apache.marmotta.ldclient.api.ldclient.LDClientService;
+import org.apache.marmotta.ldclient.api.provider.DataProvider;
+import org.apache.marmotta.ldclient.exception.DataRetrievalException;
+import org.apache.marmotta.ldclient.model.ClientResponse;
+import org.openrdf.repository.Repository;
+import org.openrdf.repository.RepositoryConnection;
+import org.openrdf.repository.RepositoryException;
+import org.openrdf.repository.sail.SailRepository;
+import org.openrdf.rio.RDFFormat;
+import org.openrdf.rio.RDFParseException;
+import org.openrdf.sail.memory.MemoryStore;
+
+import java.io.IOException;
+
+public class DummyProvider implements DataProvider {
+
+	@Override
+	public String getName() {
+		return "Dummy";
+	}
+
+	@Override
+	public String[] listMimeTypes() {
+		return new String[] {"application/dummy"};
+	}
+
+	@Override
+	public ClientResponse retrieveResource(String resource, LDClientService client, Endpoint endpoint) throws DataRetrievalException {
+        String filename = resource.substring("http://localhost/".length()) + ".ttl";
+
+        try {
+            Repository triples = new SailRepository(new MemoryStore());
+            triples.initialize();
+
+            RepositoryConnection con = triples.getConnection();
+            try {
+                con.begin();
+
+                con.add(DummyProvider.class.getResourceAsStream(filename), resource, RDFFormat.TURTLE);
+
+                con.commit();
+            } catch(RepositoryException ex) {
+                con.rollback();
+            } catch (RDFParseException e) {
+                throw new DataRetrievalException("could not parse resource data for file "+filename);
+            } catch (IOException e) {
+                throw new DataRetrievalException("could not load resource data for file "+filename);
+            } finally {
+                con.close();
+            }
+
+            ClientResponse response = new ClientResponse(200, triples);
+
+            return response;
+        } catch (RepositoryException e) {
+            throw new DataRetrievalException("could not load resource data for file "+filename);
+        }
+
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-infinispan/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyTest.java
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-infinispan/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyTest.java b/libraries/ldcache/ldcache-backend-infinispan/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyTest.java
new file mode 100644
index 0000000..15a49d8
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-infinispan/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyTest.java
@@ -0,0 +1,82 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.ldcache.services.test.dummy;
+
+import org.apache.marmotta.ldclient.api.ldclient.LDClientService;
+import org.apache.marmotta.ldclient.model.ClientResponse;
+import org.apache.marmotta.ldclient.services.ldclient.LDClient;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.openrdf.repository.RepositoryConnection;
+
+/**
+ * Test if the dummy components work.
+ * <p/>
+ * Author: Sebastian Schaffert (sschaffert@apache.org)
+ */
+public class DummyTest {
+
+    private LDClientService ldclient;
+
+
+    @Before
+    public void setupClient() {
+        ldclient = new LDClient();
+    }
+
+    @After
+    public void shutdownClient() {
+        ldclient.shutdown();
+    }
+
+    @Test
+    public void testDummyProvider() throws Exception {
+        ClientResponse resp1 = ldclient.retrieveResource("http://localhost/resource1");
+        RepositoryConnection con1 = resp1.getTriples().getConnection();
+        try {
+            con1.begin();
+            Assert.assertEquals(3, con1.size());
+            con1.commit();
+        } finally {
+            con1.close();
+        }
+
+        ClientResponse resp2 = ldclient.retrieveResource("http://localhost/resource2");
+        RepositoryConnection con2 = resp2.getTriples().getConnection();
+        try {
+            con2.begin();
+            Assert.assertEquals(2, con2.size());
+            con2.commit();
+        } finally {
+            con2.close();
+        }
+
+        ClientResponse resp3 = ldclient.retrieveResource("http://localhost/resource3");
+        RepositoryConnection con3 = resp3.getTriples().getConnection();
+        try {
+            con3.begin();
+            Assert.assertEquals(2, con3.size());
+            con3.commit();
+        } finally {
+            con3.close();
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/META-INF/services/org.apache.marmotta.ldclient.api.endpoint.Endpoint
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/META-INF/services/org.apache.marmotta.ldclient.api.endpoint.Endpoint b/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/META-INF/services/org.apache.marmotta.ldclient.api.endpoint.Endpoint
new file mode 100644
index 0000000..f2001b2
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/META-INF/services/org.apache.marmotta.ldclient.api.endpoint.Endpoint
@@ -0,0 +1 @@
+org.apache.marmotta.ldcache.services.test.dummy.DummyEndpoint
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/META-INF/services/org.apache.marmotta.ldclient.api.provider.DataProvider
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/META-INF/services/org.apache.marmotta.ldclient.api.provider.DataProvider b/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/META-INF/services/org.apache.marmotta.ldclient.api.provider.DataProvider
new file mode 100644
index 0000000..15f3621
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/META-INF/services/org.apache.marmotta.ldclient.api.provider.DataProvider
@@ -0,0 +1 @@
+org.apache.marmotta.ldcache.services.test.dummy.DummyProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/logback.xml
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/logback.xml b/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/logback.xml
new file mode 100644
index 0000000..1bfecff
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/logback.xml
@@ -0,0 +1,27 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<configuration>
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%d{HH:mm:ss.SSS} %highlight(%level) %cyan(%logger{15}) - %m%n</pattern>
+        </encoder>
+    </appender>
+    <root level="${root-level:-INFO}">
+        <appender-ref ref="CONSOLE"/>
+    </root>
+</configuration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource1.ttl
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource1.ttl b/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource1.ttl
new file mode 100644
index 0000000..71ef413
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource1.ttl
@@ -0,0 +1,21 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+@prefix ex: <http://localhost/> .
+ex:resource1 ex:property1 "Value 1" ;
+             ex:property2 ex:resource2 ;
+             ex:property3 "Value X" .
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource2.ttl
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource2.ttl b/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource2.ttl
new file mode 100644
index 0000000..5a2ce88
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource2.ttl
@@ -0,0 +1,20 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+@prefix ex: <http://localhost/> .
+ex:resource2 ex:property1 "Value 2" ;
+             ex:property2 ex:resource3 .
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource3.ttl
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource3.ttl b/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource3.ttl
new file mode 100644
index 0000000..ec03e8b
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-infinispan/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource3.ttl
@@ -0,0 +1,20 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+@prefix ex: <http://localhost/> .
+ex:resource3 ex:property1 "Value 3" ;
+             ex:property3 "Value 4" .
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-kiwi/pom.xml
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-kiwi/pom.xml b/libraries/ldcache/ldcache-backend-kiwi/pom.xml
index 881b273..2940c01 100644
--- a/libraries/ldcache/ldcache-backend-kiwi/pom.xml
+++ b/libraries/ldcache/ldcache-backend-kiwi/pom.xml
@@ -171,6 +171,16 @@
             <scope>test</scope>
             <optional>true</optional> <!-- GPL licensed, no dependency -->
         </dependency>
+        <dependency>
+            <groupId>org.apache.marmotta</groupId>
+            <artifactId>ldcache-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-rio-turtle</artifactId>
+            <scope>test</scope>
+        </dependency>
 
     </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-kiwi/src/test/java/org/apache/marmotta/ldcache/services/test/LDCacheKiWiTest.java
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-kiwi/src/test/java/org/apache/marmotta/ldcache/services/test/LDCacheKiWiTest.java b/libraries/ldcache/ldcache-backend-kiwi/src/test/java/org/apache/marmotta/ldcache/services/test/LDCacheKiWiTest.java
new file mode 100644
index 0000000..b22b600
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-kiwi/src/test/java/org/apache/marmotta/ldcache/services/test/LDCacheKiWiTest.java
@@ -0,0 +1,307 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.ldcache.services.test;
+
+import info.aduna.iteration.CloseableIteration;
+import org.apache.marmotta.kiwi.persistence.KiWiDialect;
+import org.apache.marmotta.kiwi.persistence.h2.H2Dialect;
+import org.apache.marmotta.kiwi.persistence.mysql.MySQLDialect;
+import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect;
+import org.apache.marmotta.kiwi.sail.KiWiStore;
+import org.apache.marmotta.ldcache.backend.kiwi.LDCachingKiWiBackend;
+import org.apache.marmotta.ldcache.model.CacheConfiguration;
+import org.apache.marmotta.ldcache.services.LDCache;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.openrdf.repository.Repository;
+import org.openrdf.repository.RepositoryConnection;
+import org.openrdf.repository.RepositoryException;
+import org.openrdf.repository.sail.SailRepository;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This test checks if the ldcache main class works, i.e. the system properly stores cache entries and cached triples.
+ * It will try running over all available databases. Except for in-memory databases like
+ * H2 or Derby, database URLs must be passed as system property, or otherwise the test is skipped for this database.
+ * Available system properties:
+ * <ul>
+ *     <li>PostgreSQL:
+ *     <ul>
+ *         <li>postgresql.url, e.g. jdbc:postgresql://localhost:5433/kiwitest?prepareThreshold=3</li>
+ *         <li>postgresql.user (default: lmf)</li>
+ *         <li>postgresql.pass (default: lmf)</li>
+ *     </ul>
+ *     </li>
+ *     <li>MySQL:
+ *     <ul>
+ *         <li>mysql.url, e.g. jdbc:mysql://localhost:3306/kiwitest?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull</li>
+ *         <li>mysql.user (default: lmf)</li>
+ *         <li>mysql.pass (default: lmf</li>
+ *     </ul>
+ *     </li>
+ *     <li>H2:
+ *     <ul>
+ *         <li>h2.url, e.g. jdbc:h2:mem;MVCC=true;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=10</li>
+ *         <li>h2.user (default: lmf)</li>
+ *         <li>h2.pass (default: lmf</li>
+ *     </ul>
+ *     </li>
+ * </ul>
+ *
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+@RunWith(Parameterized.class)
+public class LDCacheKiWiTest {
+
+    public static final String CACHE_CONTEXT = "http://localhost/context/cache";
+
+    /**
+     * Return database configurations if the appropriate parameters have been set.
+     *
+     * @return an array (database name, url, user, password)
+     */
+    @Parameterized.Parameters(name="Database Test {index}: {0} at {1}")
+    public static Iterable<Object[]> databases() {
+        String[] databases = {"H2", "PostgreSQL", "MySQL"};
+
+        List<Object[]> result = new ArrayList<Object[]>(databases.length);
+        for(String database : databases) {
+            if(System.getProperty(database.toLowerCase()+".url") != null) {
+                result.add(new Object[] {
+                        database,
+                        System.getProperty(database.toLowerCase()+".url"),
+                        System.getProperty(database.toLowerCase()+".user","lmf"),
+                        System.getProperty(database.toLowerCase()+".pass","lmf")
+                });
+            }
+        }
+        return result;
+    }
+
+
+    private KiWiDialect dialect;
+
+    private String jdbcUrl;
+
+    private String jdbcUser;
+
+    private String jdbcPass;
+
+    private KiWiStore store;
+
+    private LDCachingKiWiBackend backend;
+
+    private Repository repository;
+
+    private LDCache ldcache;
+
+    public LDCacheKiWiTest(String database, String jdbcUrl, String jdbcUser, String jdbcPass) {
+        this.jdbcPass = jdbcPass;
+        this.jdbcUrl = jdbcUrl;
+        this.jdbcUser = jdbcUser;
+
+        if("H2".equals(database)) {
+            this.dialect = new H2Dialect();
+        } else if("MySQL".equals(database)) {
+            this.dialect = new MySQLDialect();
+        } else if("PostgreSQL".equals(database)) {
+            this.dialect = new PostgreSQLDialect();
+        }
+    }
+
+
+    @Before
+    public void initDatabase() throws RepositoryException {
+        store = new KiWiStore("test",jdbcUrl,jdbcUser,jdbcPass,dialect, "http://localhost/context/default", "http://localhost/context/inferred");
+        repository = new SailRepository(store);
+        repository.initialize();
+
+        backend = new LDCachingKiWiBackend(store, CACHE_CONTEXT);
+        backend.initialize();
+
+        ldcache = new LDCache(new CacheConfiguration(),backend);
+    }
+
+    @After
+    public void dropDatabase() throws RepositoryException, SQLException {
+        backend.getPersistence().dropDatabase();
+        store.getPersistence().dropDatabase();
+        backend.shutdown();
+        repository.shutDown();
+    }
+
+
+    /**
+     * Test retrieving and caching some resources (provided by DummyProvider).
+     */
+    @Test
+    public void textCacheResources() throws Exception {
+        String uri1 = "http://localhost/resource1";
+        String uri2 = "http://localhost/resource2";
+        String uri3 = "http://localhost/resource3";
+
+        ldcache.refreshResource(repository.getValueFactory().createURI(uri1),false);
+
+        Assert.assertEquals(1,asList(ldcache.listCacheEntries()).size());
+
+        RepositoryConnection con1 = ldcache.getCacheConnection(uri1);
+        try {
+            con1.begin();
+            Assert.assertEquals(3, asList(con1.getStatements(con1.getValueFactory().createURI(uri1), null, null, false)).size());
+            con1.commit();
+        } finally {
+            con1.close();
+        }
+
+        ldcache.refreshResource(repository.getValueFactory().createURI(uri2),false);
+
+        Assert.assertEquals(2,asList(ldcache.listCacheEntries()).size());
+
+        RepositoryConnection con2 = ldcache.getCacheConnection(uri2);
+        try {
+            con2.begin();
+            Assert.assertEquals(2, asList(con2.getStatements(con2.getValueFactory().createURI(uri2), null, null, false)).size());
+            con2.commit();
+        } finally {
+            con2.close();
+        }
+
+        ldcache.refreshResource(repository.getValueFactory().createURI(uri3),false);
+
+        Assert.assertEquals(3,asList(ldcache.listCacheEntries()).size());
+
+        RepositoryConnection con3 = ldcache.getCacheConnection(uri3);
+        try {
+            con3.begin();
+            Assert.assertEquals(2, asList(con3.getStatements(con3.getValueFactory().createURI(uri3), null, null, false)).size());
+            con3.commit();
+        } finally {
+            con3.close();
+        }
+    }
+
+
+    /**
+     * Test retrieving and caching some resources (provided by DummyProvider).
+     */
+    @Test
+    public void textExpire() throws Exception {
+        String uri1 = "http://localhost/resource1";
+        String uri2 = "http://localhost/resource2";
+        String uri3 = "http://localhost/resource3";
+
+        ldcache.refreshResource(repository.getValueFactory().createURI(uri1),false);
+        ldcache.refreshResource(repository.getValueFactory().createURI(uri2),false);
+        ldcache.refreshResource(repository.getValueFactory().createURI(uri3),false);
+
+        Assert.assertEquals(3,asList(ldcache.listCacheEntries()).size());
+        Assert.assertEquals(0,asList(ldcache.listExpiredEntries()).size());
+
+        ldcache.expire(repository.getValueFactory().createURI(uri1));
+
+        mysqlSleep();
+
+        Assert.assertEquals(1,asList(ldcache.listExpiredEntries()).size());
+
+        ldcache.refreshExpired();
+
+        mysqlSleep();
+
+        Assert.assertEquals(0,asList(ldcache.listExpiredEntries()).size());
+
+    }
+
+    /**
+     * Test retrieving and caching some resources (provided by DummyProvider).
+     */
+    @Test
+    public void textExpireAll() throws Exception {
+        String uri1 = "http://localhost/resource1";
+        String uri2 = "http://localhost/resource2";
+        String uri3 = "http://localhost/resource3";
+
+        ldcache.refreshResource(repository.getValueFactory().createURI(uri1),false);
+        ldcache.refreshResource(repository.getValueFactory().createURI(uri2),false);
+        ldcache.refreshResource(repository.getValueFactory().createURI(uri3),false);
+
+        Assert.assertEquals(3,asList(ldcache.listCacheEntries()).size());
+        Assert.assertEquals(0,asList(ldcache.listExpiredEntries()).size());
+
+        ldcache.expireAll();
+
+        mysqlSleep();
+
+        Assert.assertEquals(3,asList(ldcache.listExpiredEntries()).size());
+
+        ldcache.refreshExpired();
+
+        mysqlSleep();
+
+        Assert.assertEquals(0,asList(ldcache.listExpiredEntries()).size());
+
+    }
+
+
+    /*
+     * MYSQL rounds timestamps to the second, so it is sometimes necessary to sleep before doing a test
+     */
+    private  void mysqlSleep() {
+        if(this.dialect instanceof MySQLDialect) {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+            }
+        } else {
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+            }
+        }
+    }
+
+    /**
+     * Workaround for https://openrdf.atlassian.net/browse/SES-1702 in Sesame 2.7.0-beta1
+     * @param <E>
+     * @return
+     */
+    public static <E,X extends Exception> List<E> asList(CloseableIteration<E,X> result) throws RepositoryException {
+        ArrayList<E> collection = new ArrayList<E>();
+        try {
+            try {
+                while (result.hasNext()) {
+                    collection.add(result.next());
+                }
+
+                return collection;
+            } finally {
+                result.close();
+            }
+        } catch(Throwable ex) {
+            throw new RepositoryException(ex);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-kiwi/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyEndpoint.java
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-kiwi/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyEndpoint.java b/libraries/ldcache/ldcache-backend-kiwi/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyEndpoint.java
new file mode 100644
index 0000000..1289776
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-kiwi/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyEndpoint.java
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.ldcache.services.test.dummy;
+
+import org.apache.marmotta.ldclient.api.endpoint.Endpoint;
+
+public class DummyEndpoint extends Endpoint {
+	
+	public DummyEndpoint() {
+		super("Dummy", "Dummy", "^http://localhost", null, 86400l);
+		setPriority(PRIORITY_HIGH);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-kiwi/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyProvider.java
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-kiwi/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyProvider.java b/libraries/ldcache/ldcache-backend-kiwi/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyProvider.java
new file mode 100644
index 0000000..4b6f92a
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-kiwi/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyProvider.java
@@ -0,0 +1,82 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.ldcache.services.test.dummy;
+
+import org.apache.marmotta.ldclient.api.endpoint.Endpoint;
+import org.apache.marmotta.ldclient.api.ldclient.LDClientService;
+import org.apache.marmotta.ldclient.api.provider.DataProvider;
+import org.apache.marmotta.ldclient.exception.DataRetrievalException;
+import org.apache.marmotta.ldclient.model.ClientResponse;
+import org.openrdf.repository.Repository;
+import org.openrdf.repository.RepositoryConnection;
+import org.openrdf.repository.RepositoryException;
+import org.openrdf.repository.sail.SailRepository;
+import org.openrdf.rio.RDFFormat;
+import org.openrdf.rio.RDFParseException;
+import org.openrdf.sail.memory.MemoryStore;
+
+import java.io.IOException;
+
+public class DummyProvider implements DataProvider {
+
+	@Override
+	public String getName() {
+		return "Dummy";
+	}
+
+	@Override
+	public String[] listMimeTypes() {
+		return new String[] {"application/dummy"};
+	}
+
+	@Override
+	public ClientResponse retrieveResource(String resource, LDClientService client, Endpoint endpoint) throws DataRetrievalException {
+        String filename = resource.substring("http://localhost/".length()) + ".ttl";
+
+        try {
+            Repository triples = new SailRepository(new MemoryStore());
+            triples.initialize();
+
+            RepositoryConnection con = triples.getConnection();
+            try {
+                con.begin();
+
+                con.add(DummyProvider.class.getResourceAsStream(filename), resource, RDFFormat.TURTLE);
+
+                con.commit();
+            } catch(RepositoryException ex) {
+                con.rollback();
+            } catch (RDFParseException e) {
+                throw new DataRetrievalException("could not parse resource data for file "+filename);
+            } catch (IOException e) {
+                throw new DataRetrievalException("could not load resource data for file "+filename);
+            } finally {
+                con.close();
+            }
+
+            ClientResponse response = new ClientResponse(200, triples);
+
+            return response;
+        } catch (RepositoryException e) {
+            throw new DataRetrievalException("could not load resource data for file "+filename);
+        }
+
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-kiwi/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyTest.java
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-kiwi/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyTest.java b/libraries/ldcache/ldcache-backend-kiwi/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyTest.java
new file mode 100644
index 0000000..15a49d8
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-kiwi/src/test/java/org/apache/marmotta/ldcache/services/test/dummy/DummyTest.java
@@ -0,0 +1,82 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.ldcache.services.test.dummy;
+
+import org.apache.marmotta.ldclient.api.ldclient.LDClientService;
+import org.apache.marmotta.ldclient.model.ClientResponse;
+import org.apache.marmotta.ldclient.services.ldclient.LDClient;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.openrdf.repository.RepositoryConnection;
+
+/**
+ * Test if the dummy components work.
+ * <p/>
+ * Author: Sebastian Schaffert (sschaffert@apache.org)
+ */
+public class DummyTest {
+
+    private LDClientService ldclient;
+
+
+    @Before
+    public void setupClient() {
+        ldclient = new LDClient();
+    }
+
+    @After
+    public void shutdownClient() {
+        ldclient.shutdown();
+    }
+
+    @Test
+    public void testDummyProvider() throws Exception {
+        ClientResponse resp1 = ldclient.retrieveResource("http://localhost/resource1");
+        RepositoryConnection con1 = resp1.getTriples().getConnection();
+        try {
+            con1.begin();
+            Assert.assertEquals(3, con1.size());
+            con1.commit();
+        } finally {
+            con1.close();
+        }
+
+        ClientResponse resp2 = ldclient.retrieveResource("http://localhost/resource2");
+        RepositoryConnection con2 = resp2.getTriples().getConnection();
+        try {
+            con2.begin();
+            Assert.assertEquals(2, con2.size());
+            con2.commit();
+        } finally {
+            con2.close();
+        }
+
+        ClientResponse resp3 = ldclient.retrieveResource("http://localhost/resource3");
+        RepositoryConnection con3 = resp3.getTriples().getConnection();
+        try {
+            con3.begin();
+            Assert.assertEquals(2, con3.size());
+            con3.commit();
+        } finally {
+            con3.close();
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-kiwi/src/test/resources/META-INF/services/org.apache.marmotta.ldclient.api.endpoint.Endpoint
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-kiwi/src/test/resources/META-INF/services/org.apache.marmotta.ldclient.api.endpoint.Endpoint b/libraries/ldcache/ldcache-backend-kiwi/src/test/resources/META-INF/services/org.apache.marmotta.ldclient.api.endpoint.Endpoint
new file mode 100644
index 0000000..f2001b2
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-kiwi/src/test/resources/META-INF/services/org.apache.marmotta.ldclient.api.endpoint.Endpoint
@@ -0,0 +1 @@
+org.apache.marmotta.ldcache.services.test.dummy.DummyEndpoint
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-kiwi/src/test/resources/META-INF/services/org.apache.marmotta.ldclient.api.provider.DataProvider
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-kiwi/src/test/resources/META-INF/services/org.apache.marmotta.ldclient.api.provider.DataProvider b/libraries/ldcache/ldcache-backend-kiwi/src/test/resources/META-INF/services/org.apache.marmotta.ldclient.api.provider.DataProvider
new file mode 100644
index 0000000..15f3621
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-kiwi/src/test/resources/META-INF/services/org.apache.marmotta.ldclient.api.provider.DataProvider
@@ -0,0 +1 @@
+org.apache.marmotta.ldcache.services.test.dummy.DummyProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-kiwi/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource1.ttl
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-kiwi/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource1.ttl b/libraries/ldcache/ldcache-backend-kiwi/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource1.ttl
new file mode 100644
index 0000000..71ef413
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-kiwi/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource1.ttl
@@ -0,0 +1,21 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+@prefix ex: <http://localhost/> .
+ex:resource1 ex:property1 "Value 1" ;
+             ex:property2 ex:resource2 ;
+             ex:property3 "Value X" .
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-kiwi/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource2.ttl
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-kiwi/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource2.ttl b/libraries/ldcache/ldcache-backend-kiwi/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource2.ttl
new file mode 100644
index 0000000..5a2ce88
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-kiwi/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource2.ttl
@@ -0,0 +1,20 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+@prefix ex: <http://localhost/> .
+ex:resource2 ex:property1 "Value 2" ;
+             ex:property2 ex:resource3 .
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-backend-kiwi/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource3.ttl
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-kiwi/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource3.ttl b/libraries/ldcache/ldcache-backend-kiwi/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource3.ttl
new file mode 100644
index 0000000..ec03e8b
--- /dev/null
+++ b/libraries/ldcache/ldcache-backend-kiwi/src/test/resources/org/apache/marmotta/ldcache/services/test/dummy/resource3.ttl
@@ -0,0 +1,20 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+@prefix ex: <http://localhost/> .
+ex:resource3 ex:property1 "Value 3" ;
+             ex:property3 "Value 4" .
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/marmotta/blob/4aa89b0b/libraries/ldcache/ldcache-core/pom.xml
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-core/pom.xml b/libraries/ldcache/ldcache-core/pom.xml
index c31faa9..448caea 100644
--- a/libraries/ldcache/ldcache-core/pom.xml
+++ b/libraries/ldcache/ldcache-core/pom.xml
@@ -138,11 +138,6 @@
 
         <!-- Testing -->
         <dependency>
-            <groupId>org.apache.marmotta</groupId>
-            <artifactId>ldcache-backend-kiwi</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <artifactId>junit</artifactId>
             <groupId>junit</groupId>
             <scope>test</scope>
@@ -167,27 +162,6 @@
             <artifactId>logback-classic</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>com.h2database</groupId>
-            <artifactId>h2</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.postgresql</groupId>
-            <artifactId>postgresql</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>mysql</groupId>
-            <artifactId>mysql-connector-java</artifactId>
-            <scope>test</scope>
-            <optional>true</optional> <!-- GPL licensed, no dependency -->
-        </dependency>
-        <dependency>
-            <groupId>org.openrdf.sesame</groupId>
-            <artifactId>sesame-rio-turtle</artifactId>
-            <scope>test</scope>
-        </dependency>
 
     </dependencies>
 </project>