rdf4j
rdf4j copied to clipboard
Repository level control of read/write and read-only
Current Behavior
Here it's more a design issue that I want to point out, unless I misunderstood something.
For example, if I want to share the same MemoryStore for two different repositories, where one is read-only and the other is read-write.
private val memoryStore = MemoryStore()
private val rdfReaderRepository: Repository = SailRepository(memoryStore)
private val rdfWriterRepository: Repository = SailRepository(memoryStore)
In this case, we have the function:
@Override
public boolean isWritable() throws RepositoryException {
try {
if (!isInitialized()) {
init();
}
return sail.isWritable();
} catch (SailException e) {
throw new RepositoryException("Unable to determine writable status of Sail", e);
}
}
It means the repository is relying on the sail to know if it's read or write, but in my opinion, it should be possible to define the repository to read only even though the MemoryStore allows read-write.
Expected Behavior
We should be able to do this:
private val memoryStore = MemoryStore()
private val rdfReaderRepository: Repository = SailRepository(memoryStore, false)
private val rdfWriterRepository: Repository = SailRepository(memoryStore, true)
Where the additional parameter allows to define if it's writable or not, under the hood, if we pass true but the memory store itself is configured with false, we should throw an exception, but otherwise I don't see why we couldn't restrict the access to read only.
As a workaround, we could also use the SailWrapper to change the response from the MemoryStore implementation, but that would look more like a workaround.
Steps To Reproduce
private val memoryStore = MemoryStore()
private val rdfReaderRepository: Repository = SailRepository(memoryStore)
private val rdfWriterRepository: Repository = SailRepository(memoryStore)
Version
4.2.4
Are you interested in contributing a solution yourself?
No
Anything else?
In my case, I simply try to simulate the AWS Neptune endpoints with read only access vs read-write, so to have more accurate tests, it's important to be able to limit the type of queries we are building with the Repository.
It isn't intended to share a Sail between multiple SailRepositories. I know others have solved similar issues at the endpoint level, ex. ReadOnlySparqlApplication.java
I feel the in-memory solution is very good and the design should be extended in that case, because if you want to simulate a DB, then it would make sense in my opinion have the option to define if the repository is read only or not and share the same DB with multiple repositories. Don't you agree the SailWrapper would still be a good candidate to handle defining two different writable options for two repository? (in that case, it would be more a feature request)
It's definitely a use case that is worth investigating. I would lean towards an authentication/role-based solution instead since that would solve what you are trying to do while at the same time allowing for more flexibility.
@abrokenjester knows more about the intentions behind the architecture than I do. Maybe he can chime in on the idea of sharing a sail between multiple repositories, and if adding restrictions like read-only would work at the repository level.