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
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package org.javastro.ivoa.quarkus.tap;


import jakarta.transaction.Transactional;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.*;
import org.javastro.ivoa.quarkus.tap.upload.QuarkusTapUploader;
Expand Down Expand Up @@ -46,18 +47,19 @@ protected Response redirectToJob(String jobid) {
}

//IMPL the two query endpoints are in different resources for routing purposes
@POST
@Consumes({MediaType.APPLICATION_FORM_URLENCODED, MediaType.MULTIPART_FORM_DATA})
public Response async(@RestForm("QUERY") String query, @RestForm("LANG") String lang, @RestForm("RESPONSEFORMAT") String responseformat,
@RestForm("MAXREC") Long maxrec, @RestForm("RUNID") String runid,
@RestForm("UPLOAD") String upload, MultipartFormDataInput input, @Context UriInfo uriInfo) throws UWSException {
TAPUploadCacher tapUploader = new NullUploader();
if(upload != null && !upload.isEmpty() ) {
@POST
@Consumes({MediaType.APPLICATION_FORM_URLENCODED, MediaType.MULTIPART_FORM_DATA})
@Transactional
public Response async(@RestForm("QUERY") String query, @RestForm("LANG") String lang, @RestForm("RESPONSEFORMAT") String responseformat,
@RestForm("MAXREC") Long maxrec, @RestForm("RUNID") String runid,
@RestForm("UPLOAD") String upload, MultipartFormDataInput input, @Context UriInfo uriInfo) throws UWSException {
TAPUploadCacher tapUploader = new NullUploader();
if(upload != null && !upload.isEmpty() ) {
tapUploader = new QuarkusTapUploader(upload, input);
}
BaseUWSJob job = getTapHelper().getJobmanager().createJob(new TAPJobSpecification(query,lang,responseformat,maxrec,runid,tapUploader));
return Response.seeOther(getTapHelper().asyncJobUri(job.getID())).build();
}
}
BaseUWSJob job = getTapHelper().getJobmanager().createJob(new TAPJobSpecification(query,lang,responseformat,maxrec,runid,tapUploader));
return Response.seeOther(getTapHelper().asyncJobUri(job.getID())).build();
}

@GET
@Path("{jobid}/results/result")
Expand All @@ -68,4 +70,22 @@ public RestResponse<java.nio.file.Path> getVotable(@PathParam("jobid") String jo
.header(HttpHeaders.CONTENT_DISPOSITION, "result.vot")
.build();
}

//----------------------- Need to make database modifying operations transactional ----------------------------------
// Which means the base UWS modifying tasks need to be wrapped in a transactional override
@Override
@DELETE
@Path("{jobid}")
@Transactional
public Response deleteJob(@PathParam("jobid")String jobid) throws UWSException {
return super.deleteJob(jobid);
}

@Override
@POST
@Path("{jobid}/phase")
@Transactional
public Response setPhase(@PathParam("jobid") String jobid, @FormParam("PHASE") String phase) throws UWSException {
return super.setPhase(jobid, phase);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.infrastructure.Infrastructure;
import jakarta.inject.Inject;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
Expand Down Expand Up @@ -43,6 +44,9 @@
*/
public abstract class BaseSyncTAPResource {

@Inject
TAPJobService jobService;

protected static final Logger log = LoggerFactory.getLogger(BaseSyncTAPResource.class);

/**
Expand Down Expand Up @@ -91,9 +95,7 @@ protected Uni<Path> handleJob(String query, String lang, String responseformat,
if(upload != null && !upload.isEmpty() ) {
tapUploader = new QuarkusTapUploader(upload, input);
}
job = (TAPJob) getTapHelper().getJobmanager().createJob(
new TAPJobSpecification(query, lang, responseformat, maxrec, runid, tapUploader)
);
job = jobService.createJob(new TAPJobSpecification(query, lang, responseformat, maxrec, runid, tapUploader));

getTapHelper().getJobmanager().runJob(job.getID()); // automatically run the job
} catch (UWSException e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.javastro.ivoa.quarkus.tap;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.transaction.Transactional;
import org.javastro.ivoacore.tap.TAPJob;
import org.javastro.ivoacore.tap.TAPJobSpecification;
import org.javastro.ivoacore.uws.UWSException;

/**
* TAPJobService is responsible for managing the creation of TAPJob instances
* based on provided specifications. It relies on TAPHelper to handle the
* underlying operations associated with job management.
* <p>
* This service is application-scoped, ensuring a single instance is used
* throughout the application context. In a multithreaded environment,
* the service is designed to be thread-safe.
*/
@ApplicationScoped
public class TAPJobService {

private final TAPHelper tapHelper;

public TAPJobService(TAPHelper tapHelper) {
this.tapHelper = tapHelper;
}

@Transactional
public TAPJob createJob(TAPJobSpecification spec) throws UWSException {
return (TAPJob) tapHelper.getJobmanager().createJob(spec);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,4 @@ public class AsyncQueryResource extends BaseAsyncTAPResource {
protected TAPHelper getTapHelper() {
return tapHelper;
}

}
3 changes: 0 additions & 3 deletions src/main/java/org/javastro/ivoa/tap/QueryResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,12 @@
@Path("sync")
public class QueryResource extends BaseSyncTAPResource {


@ConfigProperty(name="ivoa.tap.sync-timeout-seconds", defaultValue = "5")
int syncTimeoutSeconds;


@Inject
TAPHelper tapHelper;


@Override
protected TAPHelper getTapHelper() {
return tapHelper;
Expand Down
25 changes: 22 additions & 3 deletions src/main/java/org/javastro/ivoa/tap/TapConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,29 @@
package org.javastro.ivoa.tap;


import io.quarkus.hibernate.orm.PersistenceUnit;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Produces;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import jakarta.persistence.EntityManager;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.javastro.ivoa.entities.resource.Capability;
import org.javastro.ivoa.entities.vosi.capabilities.Capabilities;
import org.javastro.ivoa.quarkus.tap.TAPHelper;
import org.javastro.ivoacore.common.ServiceLocator;
import org.javastro.ivoacore.tap.TAPJob;
import org.javastro.ivoacore.tap.TAPJobSpecification;
import org.javastro.ivoacore.tap.schema.SchemaProvider;
import org.javastro.ivoacore.tap.schema.VODMLSchemaProvider;
import org.javastro.ivoacore.uws.JobFactoryAggregator;
import org.javastro.ivoacore.uws.JobManager;
import org.javastro.ivoacore.uws.environment.DefaultEnvironmentFactory;
import org.javastro.ivoacore.uws.environment.DefaultExecutionPolicy;
import org.javastro.ivoacore.uws.environment.EnvironmentFactory;
import org.javastro.ivoacore.uws.persist.MemoryBasedJobStore;
import org.javastro.ivoacore.uws.persist.CachedJobStore;
import org.javastro.ivoacore.uws.persist.DatabaseJobStore;
import org.javastro.ivoacore.uws.persist.JobStore;
import org.javastro.ivoacore.vosi.CapabilityBuilder;
import org.javastro.ivoacore.vosi.VOSIProvider;

Expand All @@ -47,6 +53,10 @@ public class TapConfiguration {
@Inject
DataSource ds;

@Inject
@PersistenceUnit("uwsstore")
EntityManager em;

@ConfigProperty(name="ivoa.tap.dbCaseSensitive", defaultValue = "false")
boolean isDbCaseSensitive;

Expand Down Expand Up @@ -104,9 +114,18 @@ JobManager uws(SchemaProvider schemaProvider) {
}

EnvironmentFactory env = new DefaultEnvironmentFactory(tmpdir);
MemoryBasedJobStore store = new MemoryBasedJobStore();

TAPJob.JobFactory tapJobFactory = new TAPJob.JobFactory(ds, schemaProvider, env);

JobStore store = new CachedJobStore(
DatabaseJobStore.forJobType(
em,
TAPJobSpecification.class,
"TAP"
)
);
DefaultExecutionPolicy policy = new DefaultExecutionPolicy();
return new JobManager(new TAPJob.JobFactory(ds, schemaProvider, env), store, policy);
return new JobManager(tapJobFactory, store, policy);
}

@Produces
Expand Down
29 changes: 19 additions & 10 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,34 @@ quarkus.datasource.devservices.enabled=true
#fix port
%dev.quarkus.datasource.devservices.port=54771
quarkus.datasource.devservices.image-name=images.dev.uksrc.org/library/postgres-pgsphere14:latest
#quarkus.datasource.devservices.image-name=postgis/postgis:14-3.5
#
# PGSphere
quarkus.hibernate-orm.dialect=org.javastro.ivoacore.pgsphere.PgSphereDialect
quarkus.hibernate-orm.schema-management.create-schemas=true


#ORM setup - mainly for the TAPSchema
#default PU ORM setup - mainly for the TAPSchema
quarkus.hibernate-orm.packages=org.ivoa.dm,org.ivoa.vodml.stdtypes,org.javastro.ivoacore.pgsphere,org.javastro.ivoa.tap.entities
#%dev,%test.quarkus.hibernate-orm.database.generation=drop-and-create
%prod.quarkus.hibernate-orm.database.generation=update
quarkus.hibernate-orm.database.generation.create-schemas=true
quarkus.hibernate-orm.database.generation.halt-on-error=false
quarkus.hibernate-orm.quote-identifiers.strategy = all

# below is new quarkus
#quarkus.hibernate-orm.schema-management.strategy=drop-and-create
# older quarkus
quarkus.hibernate-orm.schema-management.strategy=drop-and-create
# this is for the scripts
quarkus.hibernate-orm.scripts.generation=drop-and-create
quarkus.hibernate-orm.scripts.generation.create-target=TAPddl.sql
quarkus.hibernate-orm.scripts.generation.drop-target=TAP_drop_ddl.sql

quarkus.hibernate-orm.log.sql=true
quarkus.hibernate-orm.log.bind-parameters=true

#datasource/PU ORM setup for UWS storage (TODO are the quotes necessary? The examples have them)
#if a separate database is needed then the datasource should be created and the datasource name should be used here instead of <default>
#quarkus.datasource."uwsstore".db-kind=postgresql
quarkus.hibernate-orm."uwsstore".packages=org.javastro.ivoacore.uws.persist
quarkus.hibernate-orm."uwsstore".schema-management.strategy=drop-and-create
quarkus.hibernate-orm."uwsstore".schema-management.create-schemas=true
quarkus.hibernate-orm."uwsstore".datasource=<default>



#image build
quarkus.container-image.builder=docker
Expand All @@ -69,4 +73,9 @@ quarkus.kubernetes.ingress.path-type=Prefix


#attempt to reduce logging noise from netty websocket
quarkus.log.category."io.netty.handler.codec.http.websocketx".use-parent-handlers=false
quarkus.log.category."io.netty.handler.codec.http.websocketx".use-parent-handlers=false

# quarkus-tap-lib contains base JAX-RS/CDI resource classes with interceptor annotations
# such as @Transactional. Index it so Quarkus can see those annotations at build time.
quarkus.index-dependency.quarkus-tap-lib.group-id=org.javastro.ivoa.servers
quarkus.index-dependency.quarkus-tap-lib.artifact-id=quarkus-tap-lib
Loading