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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,13 @@
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>client</artifactId>
<version>4.2.10</version>
<version>4.2.11-SNAPSHOT</version>
<classifier>classes</classifier>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>client</artifactId>
<version>4.2.10</version>
<version>4.2.11-SNAPSHOT</version>
<type>war</type>
</dependency>
<!-- required by jsonld-java - version same as Jersey's HTTP Client -->
Expand Down
16 changes: 2 additions & 14 deletions src/main/java/com/atomgraph/linkeddatahub/resource/Add.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,21 @@
import com.atomgraph.core.MediaTypes;
import com.atomgraph.core.vocabulary.SD;
import com.atomgraph.linkeddatahub.client.GraphStoreClient;
import com.atomgraph.linkeddatahub.model.Service;
import com.atomgraph.linkeddatahub.server.security.AgentContext;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.Optional;
import jakarta.inject.Inject;
import jakarta.ws.rs.BadRequestException;
import jakarta.ws.rs.DefaultValue;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.client.Entity;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.Request;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.SecurityContext;
import jakarta.ws.rs.core.StreamingOutput;
import jakarta.ws.rs.core.UriInfo;
import jakarta.ws.rs.ext.Providers;
import org.apache.jena.ontology.Ontology;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ResIterator;
import org.apache.jena.rdf.model.Resource;
Expand Down Expand Up @@ -67,18 +62,13 @@ public class Add
* @param request current request
* @param uriInfo current URI info
* @param mediaTypes supported media types
* @param application matched application
* @param ontology matched application's ontology
* @param service matched application's service
* @param providers JAX-RS providers
* @param system system application
* @param securityContext JAX-RS security context
* @param agentContext authenticated agent's context
*/
@Inject
public Add(@Context Request request, @Context UriInfo uriInfo, MediaTypes mediaTypes,
com.atomgraph.linkeddatahub.apps.model.Application application, Optional<Ontology> ontology, Optional<Service> service,
@Context SecurityContext securityContext, Optional<AgentContext> agentContext,
Optional<AgentContext> agentContext,
@Context Providers providers, com.atomgraph.linkeddatahub.Application system)
{
this.uriInfo = uriInfo;
Expand All @@ -92,12 +82,10 @@ public Add(@Context Request request, @Context UriInfo uriInfo, MediaTypes mediaT
* Expects a model containing a resource with dct:source (source URI) and sd:name (target graph URI) properties.
*
* @param model the RDF model containing the import parameters
* @param defaultGraph whether to import into the default graph
* @param graphUri the target graph URI
* @return JAX-RS response with the imported data
*/
@POST
public Response post(Model model, @QueryParam("default") @DefaultValue("false") Boolean defaultGraph, @QueryParam("graph") URI graphUri)
public Response post(Model model)
{
ResIterator it = model.listSubjectsWithProperty(DCTerms.source);
try
Expand Down
141 changes: 95 additions & 46 deletions src/main/java/com/atomgraph/linkeddatahub/resource/Generate.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,11 @@
*/
package com.atomgraph.linkeddatahub.resource;

import com.atomgraph.client.util.DataManager;
import com.atomgraph.core.MediaTypes;
import com.atomgraph.linkeddatahub.apps.model.Application;
import com.atomgraph.linkeddatahub.client.GraphStoreClient;
import com.atomgraph.linkeddatahub.imports.QueryLoader;
import com.atomgraph.linkeddatahub.model.Service;
import com.atomgraph.linkeddatahub.server.filter.response.CacheInvalidationFilter;
import com.atomgraph.linkeddatahub.server.model.impl.GraphStoreImpl;
import com.atomgraph.linkeddatahub.server.model.impl.DirectGraphStoreImpl;
import com.atomgraph.linkeddatahub.server.security.AgentContext;
import com.atomgraph.linkeddatahub.server.util.Skolemizer;
import com.atomgraph.linkeddatahub.vocabulary.LDH;
Expand All @@ -37,29 +35,24 @@
import java.util.UUID;
import jakarta.inject.Inject;
import jakarta.ws.rs.BadRequestException;
import jakarta.ws.rs.DefaultValue;
import jakarta.ws.rs.InternalServerErrorException;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.container.ResourceContext;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.Request;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.SecurityContext;
import jakarta.ws.rs.core.Response.Status;
import jakarta.ws.rs.core.UriBuilder;
import jakarta.ws.rs.core.UriInfo;
import jakarta.ws.rs.ext.Providers;
import org.apache.jena.ontology.Ontology;
import org.apache.jena.query.ParameterizedSparqlString;
import org.apache.jena.query.Query;
import org.apache.jena.query.Syntax;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.ResIterator;
import org.apache.jena.rdf.model.Resource;
import org.apache.jena.rdf.model.ResourceFactory;
import org.apache.jena.vocabulary.DCTerms;
import org.apache.jena.vocabulary.RDF;
import org.glassfish.jersey.uri.UriComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -68,39 +61,53 @@
*
* @author {@literal Martynas Jusevičius <[email protected]>}
*/
public class Generate extends GraphStoreImpl
public class Generate
{

private static final Logger log = LoggerFactory.getLogger(Generate.class);

private final UriInfo uriInfo;
private final MediaTypes mediaTypes;
private final Application application;
private final Optional<AgentContext> agentContext;
private final com.atomgraph.linkeddatahub.Application system;
private final ResourceContext resourceContext;

/**
* Constructs endpoint for container generation.
*
*
* @param request current request
* @param uriInfo current URI info
* @param mediaTypes supported media types
* @param application matched application
* @param ontology matched application's ontology
* @param service matched application's service
* @param providers JAX-RS providers
* @param system system application
* @param securityContext JAX-RS security context
* @param agentContext authenticated agent's context
* @param dataManager RDF data manager
* @param resourceContext resource context for creating resources
*/
@Inject
public Generate(@Context Request request, @Context UriInfo uriInfo, MediaTypes mediaTypes,
com.atomgraph.linkeddatahub.apps.model.Application application, Optional<Ontology> ontology, Optional<Service> service,
@Context SecurityContext securityContext, Optional<AgentContext> agentContext,
@Context Providers providers, com.atomgraph.linkeddatahub.Application system,
DataManager dataManager)
com.atomgraph.linkeddatahub.apps.model.Application application, Optional<AgentContext> agentContext,
com.atomgraph.linkeddatahub.Application system, @Context ResourceContext resourceContext)
{
super(request, uriInfo, mediaTypes, application, ontology, service, securityContext, agentContext, providers, system);
this.uriInfo = uriInfo;
this.mediaTypes = mediaTypes;
this.application = application;
this.agentContext = agentContext;
this.system = system;
this.resourceContext = resourceContext;
}


/**
* Generates containers for given classes.
* Expects a model containing a parent container (<samp>sioc:has_parent</samp>) and one or more class specifications
* with <samp>void:class</samp> and <samp>spin:query</samp> properties. Creates a new container for each class with a view based
* on the provided SPARQL <samp>SELECT</samp> query.
*
* @param model the RDF model containing the generation parameters
* @return JAX-RS response indicating success or failure
*/
@POST
@Override
public Response post(Model model, @QueryParam("default") @DefaultValue("false") Boolean defaultGraph, @QueryParam("graph") URI graphUri)
public Response post(Model model)
{
ResIterator it = model.listSubjectsWithProperty(SIOC.HAS_PARENT);
try
Expand Down Expand Up @@ -143,9 +150,10 @@ public Response post(Model model, @QueryParam("default") @DefaultValue("false")
service)));
new Skolemizer(containerGraphURI.toString()).apply(containerModel);

try (Response containerResponse = super.post(containerModel, false, containerGraphURI))
// append triples directly to the graph store without doing an HTTP request (and thus no ACL check)
try (Response containerResponse = getResourceContext().getResource(DirectGraphStoreImpl.class).post(containerModel, false, containerGraphURI))
{
if (containerResponse.getStatus() != Response.Status.CREATED.getStatusCode())
if (!containerResponse.getStatusInfo().getFamily().equals(Status.Family.SUCCESSFUL))
{
if (log.isErrorEnabled()) log.error("Cannot create container");
throw new InternalServerErrorException("Cannot create container");
Expand All @@ -159,10 +167,7 @@ public Response post(Model model, @QueryParam("default") @DefaultValue("false")
}

// ban the parent container URI from proxy cache to make sure the next query using it will be fresh (e.g. SELECT that loads children)
try (Response response = ban(getApplication().getService().getBackendProxy(), parent.getURI()))
{
// Response automatically closed by try-with-resources
}
getSystem().ban(getApplication().getService().getBackendProxy(), parent.getURI(), true);

return Response.ok().build();
}
Expand Down Expand Up @@ -211,7 +216,7 @@ public Resource createContainer(Model model, URI graphURI, Resource parent, Stri
addLiteral(DCTerms.title, title).
addLiteral(DH.slug, UUID.randomUUID().toString()).
addLiteral(DCTerms.created, Calendar.getInstance()).
addProperty(ResourceFactory.createProperty(RDF.getURI(), "_1"), content);
addProperty(model.createProperty(RDF.getURI(), "_1"), content); // TO-DO: make sure we're creating sequence value larger than the existing ones?
}

/**
Expand All @@ -228,20 +233,64 @@ public Resource createView(Model model, Resource query)
addProperty(SPIN.query, query);
}

/**
* Bans URL from the backend proxy cache.
*
* @param proxy proxy server URL
* @param url banned URL
* @return proxy server response
/**
* Returns the supported media types.
*
* @return media types
*/
public Response ban(Resource proxy, String url)
public MediaTypes getMediaTypes()
{
if (url == null) throw new IllegalArgumentException("Resource cannot be null");

return getSystem().getClient().target(proxy.getURI()).request().
header(CacheInvalidationFilter.HEADER_NAME, UriComponent.encode(url, UriComponent.Type.UNRESERVED)). // the value has to be URL-encoded in order to match request URLs in Varnish
method("BAN", Response.class);
return mediaTypes;
}


/**
* Returns the current application.
*
* @return the application
*/
public Application getApplication()
{
return application;
}

/**
* Returns the current URI info.
*
* @return URI info
*/
public UriInfo getUriInfo()
{
return uriInfo;
}

/**
* Returns the authenticated agent's context.
*
* @return optional agent context
*/
public Optional<AgentContext> getAgentContext()
{
return agentContext;
}

/**
* Returns the system application.
*
* @return system application
*/
public com.atomgraph.linkeddatahub.Application getSystem()
{
return system;
}

/**
* Returns the resource context.
*
* @return resource context
*/
public ResourceContext getResourceContext()
{
return resourceContext;
}

}
Loading