From 3e0e73ecb12b74ae0b8cc1339c96ccbb19782b0b Mon Sep 17 00:00:00 2001 From: Brian Long Date: Wed, 1 Feb 2023 14:54:15 -0500 Subject: [PATCH] split to poststats-api/api-site --- pom.xml | 179 +++--------------- src/local/jetty.xml | 4 - .../com/poststats/api/golf/Application.java | 8 - .../api/golf/service/EventService.java | 7 - .../impl/DatabaseEventPersonService.java | 89 --------- .../service/impl/DatabaseEventService.java | 38 ---- .../java/com/poststats/golf/api/EventApi.java | 76 ++++++++ .../golf => golf/api}/EventFinanceApi.java | 92 ++++----- .../golf => golf/api}/EventPersonApi.java | 178 ++++++++--------- .../com/poststats/golf/api/GolferApi.java | 60 ++++++ .../com/poststats/golf/api/SeriesApi.java | 113 +++++++++++ .../{api/golf => golf/api}/VersionApi.java | 19 +- .../com/poststats/golf/api/model/Event.java | 126 ++++++++++++ .../poststats/golf/api/model/EventDetail.java | 11 ++ .../com/poststats/golf/api/model/Series.java | 50 +++++ .../java/com/poststats/golf/package-info.java | 4 + .../security/EventPersonSecurityContext.java | 38 ++++ .../golf/service/EventFinanceService.java | 7 +- .../golf/service/EventPersonService.java | 11 +- .../poststats/golf/service/EventService.java | 19 ++ .../golf/service/SeriesPersonService.java | 7 +- .../poststats/golf/service/SeriesService.java | 11 ++ .../service/db/EventFinanceServiceDAO.java} | 43 +++-- .../service/db/EventPersonServiceDAO.java | 96 ++++++++++ .../golf/service/db/EventServiceDAO.java | 170 +++++++++++++++++ .../golf/service/db/SeriesServiceDAO.java | 82 ++++++++ .../poststats/golf/servlet/EventFilter.java | 57 ++++++ .../poststats/golf/servlet/SeriesFilter.java | 48 +++++ .../golf/transformer/EventTransformer.java | 41 ++++ .../golf/transformer/GolferTransformer.java | 29 +++ .../golf/transformer/SeriesTransformer.java | 28 +++ src/main/resources/META-INF/beans.xml | 5 + ...stats.api.golf.service.EventFinanceService | 1 - ...tstats.api.golf.service.EventPersonService | 1 - ...om.poststats.api.golf.service.EventService | 1 - src/main/webapp/WEB-INF/web.xml | 24 --- .../golf => golf/api}/VersionApiUnitTest.java | 27 +-- src/test/resources/log4j2.properties | 19 ++ 38 files changed, 1285 insertions(+), 534 deletions(-) delete mode 100644 src/local/jetty.xml delete mode 100644 src/main/java/com/poststats/api/golf/Application.java delete mode 100644 src/main/java/com/poststats/api/golf/service/EventService.java delete mode 100644 src/main/java/com/poststats/api/golf/service/impl/DatabaseEventPersonService.java delete mode 100644 src/main/java/com/poststats/api/golf/service/impl/DatabaseEventService.java create mode 100644 src/main/java/com/poststats/golf/api/EventApi.java rename src/main/java/com/poststats/{api/golf => golf/api}/EventFinanceApi.java (58%) rename src/main/java/com/poststats/{api/golf => golf/api}/EventPersonApi.java (52%) create mode 100644 src/main/java/com/poststats/golf/api/GolferApi.java create mode 100644 src/main/java/com/poststats/golf/api/SeriesApi.java rename src/main/java/com/poststats/{api/golf => golf/api}/VersionApi.java (74%) create mode 100644 src/main/java/com/poststats/golf/api/model/Event.java create mode 100644 src/main/java/com/poststats/golf/api/model/EventDetail.java create mode 100644 src/main/java/com/poststats/golf/api/model/Series.java create mode 100644 src/main/java/com/poststats/golf/package-info.java create mode 100644 src/main/java/com/poststats/golf/security/EventPersonSecurityContext.java rename src/main/java/com/poststats/{api => }/golf/service/EventFinanceService.java (78%) rename src/main/java/com/poststats/{api => }/golf/service/EventPersonService.java (85%) create mode 100644 src/main/java/com/poststats/golf/service/EventService.java rename src/main/java/com/poststats/{api => }/golf/service/SeriesPersonService.java (82%) create mode 100644 src/main/java/com/poststats/golf/service/SeriesService.java rename src/main/java/com/poststats/{api/golf/service/impl/DatabaseEventFinanceService.java => golf/service/db/EventFinanceServiceDAO.java} (83%) create mode 100644 src/main/java/com/poststats/golf/service/db/EventPersonServiceDAO.java create mode 100644 src/main/java/com/poststats/golf/service/db/EventServiceDAO.java create mode 100644 src/main/java/com/poststats/golf/service/db/SeriesServiceDAO.java create mode 100644 src/main/java/com/poststats/golf/servlet/EventFilter.java create mode 100644 src/main/java/com/poststats/golf/servlet/SeriesFilter.java create mode 100644 src/main/java/com/poststats/golf/transformer/EventTransformer.java create mode 100644 src/main/java/com/poststats/golf/transformer/GolferTransformer.java create mode 100644 src/main/java/com/poststats/golf/transformer/SeriesTransformer.java create mode 100644 src/main/resources/META-INF/beans.xml delete mode 100644 src/main/webapp/META-INF/com.poststats.api.golf.service.EventFinanceService delete mode 100644 src/main/webapp/META-INF/com.poststats.api.golf.service.EventPersonService delete mode 100644 src/main/webapp/META-INF/com.poststats.api.golf.service.EventService delete mode 100644 src/main/webapp/WEB-INF/web.xml rename src/test/java/com/poststats/{api/golf => golf/api}/VersionApiUnitTest.java (62%) create mode 100644 src/test/resources/log4j2.properties diff --git a/pom.xml b/pom.xml index 382525e..082d427 100644 --- a/pom.xml +++ b/pom.xml @@ -1,54 +1,37 @@ 4.0.0 - com.poststats + com.poststats.golf golf-api 1.0-SNAPSHOT - war + jar - 1.8 - 1.8 + utf-8 + 11 + 11 + 11 true lines,vars,source - - poststats.com - /var/local/tomcat7-${env} - ${server.path.tomcat}/shared/classes - ${server.path.tomcat}/webapps/golf.api.poststats.com - org.glassfish.jersey.bundles - jaxrs-ri - 2.26 + com.poststats + poststats-api + 1.0-SNAPSHOT + + + com.poststats.golf + golf-core + 1.0-SNAPSHOT org.apache.commons commons-csv 1.5 - - com.poststats.golf - db - 4.3-SNAPSHOT - - - com.poststats - db - 4.3-SNAPSHOT - - - com.poststats - commons-api - 1.0-SNAPSHOT - - - com.fasterxml.jackson.core - jackson-databind - 2.8.7 - + junit junit @@ -58,137 +41,19 @@ - - - org.apache.maven.wagon - wagon-ssh - 2.10 - - - org.eclipse.jetty - jetty-maven-plugin - 9.4.8.v20171121 + io.repaint.maven + tiles-maven-plugin + 2.33 + true - 10 - - - 8080 - 60000 - - - - / - - ${project.build.directory}/${project.artifactId}-${project.version} - - ${basedir}/../../poststats-db/db/src/${env},${basedir}/../../golf-db/db/src/${env},${basedir}/src/${env}/resources - - ${basedir}/src/${env}/jetty.xml - true + + com.poststats:source-format-tile:[1.0.0,1.1.0) + - - com.webcohesion.enunciate - enunciate-maven-plugin - 2.9.1 - - ${project.build.directory}/${project.build.finalName} - ${basedir}/enunciate.xml - - - - compile - - docs - - - - - - - - digitalocean-env - - - env - - - - - - org.codehaus.mojo - wagon-maven-plugin - 1.0 - - digitalocean-poststats - - - - upload-config-to-server - install - - upload - - - ${basedir}/src/${env}/resources - scp://${server.hostname}${server.path.configs} - - - - - - - - - digitalocean-deploy - - - env - - - - - - org.codehaus.mojo - wagon-maven-plugin - 1.0 - - digitalocean-poststats - - - - upload-war-to-server - install - - upload-single - - - ${project.build.directory}/${project.build.finalName}.war - scp://${server.hostname}/tmp - - - - deploy-war-in-server - install - - sshexec - - - scp://${server.hostname} - - mv /tmp/${project.build.finalName}.war ${server.path.webapps}/ROOT.war - - - - - - - - - diff --git a/src/local/jetty.xml b/src/local/jetty.xml deleted file mode 100644 index 03391da..0000000 --- a/src/local/jetty.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/main/java/com/poststats/api/golf/Application.java b/src/main/java/com/poststats/api/golf/Application.java deleted file mode 100644 index 15a23ae..0000000 --- a/src/main/java/com/poststats/api/golf/Application.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.poststats.api.golf; - -import javax.ws.rs.ApplicationPath; - -@ApplicationPath("golf") -public class Application extends javax.ws.rs.core.Application { - -} diff --git a/src/main/java/com/poststats/api/golf/service/EventService.java b/src/main/java/com/poststats/api/golf/service/EventService.java deleted file mode 100644 index f6c2e51..0000000 --- a/src/main/java/com/poststats/api/golf/service/EventService.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.poststats.api.golf.service; - -public interface EventService { - - int getSeriesId(long eventId); - -} diff --git a/src/main/java/com/poststats/api/golf/service/impl/DatabaseEventPersonService.java b/src/main/java/com/poststats/api/golf/service/impl/DatabaseEventPersonService.java deleted file mode 100644 index 776c1eb..0000000 --- a/src/main/java/com/poststats/api/golf/service/impl/DatabaseEventPersonService.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.poststats.api.golf.service.impl; - -import java.sql.Connection; -import java.sql.SQLException; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Response.Status; - -import com.brianlong.sql.DataSet; -import com.brianlong.sql.FlexPreparedStatement; -import com.poststats.api.golf.service.EventPersonService; -import com.poststats.sql.PostStatsDataSource; - -public class DatabaseEventPersonService implements EventPersonService { - - @Override - public List getPeople(long eventId) { - Connection dbcon = PostStatsDataSource.getInstance().acquire(true); - try { - return this.queryPersons(dbcon, eventId); - } catch (SQLException se) { - throw new WebApplicationException("Database call failure", se, Status.INTERNAL_SERVER_ERROR); - } finally { - PostStatsDataSource.getInstance().release(dbcon); - } - } - - @Override - public List getParticipants(long eventId) { - Connection dbcon = PostStatsDataSource.getInstance().acquire(true); - try { - return this.queryParticipants(dbcon, eventId); - } catch (SQLException se) { - throw new WebApplicationException("Database call failure", se, Status.INTERNAL_SERVER_ERROR); - } finally { - PostStatsDataSource.getInstance().release(dbcon); - } - } - - @Override - public Set getSeriesEventIdsAsParticipant(int seriesId, long personId) { - Connection dbcon = PostStatsDataSource.getInstance().acquire(true); - try { - return this.querySeriesEventIdsAsParticipant(dbcon, seriesId, personId); - } catch (SQLException se) { - throw new WebApplicationException("Database call failure", se, Status.INTERNAL_SERVER_ERROR); - } finally { - PostStatsDataSource.getInstance().release(dbcon); - } - } - - private List queryPersons(Connection dbcon, long eventId) throws SQLException { - FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, SQL_SELECT_PERSONS); - try { - fps.setIntegerU(1, eventId); - return fps.executeQuery().getAllRows(); - } finally { - fps.close(); - } - } - - private List queryParticipants(Connection dbcon, long eventId) throws SQLException { - FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, SQL_SELECT_PARTICIPANTS); - try { - fps.setIntegerU(1, eventId); - return fps.executeQuery().getAllRows(); - } finally { - fps.close(); - } - } - - private Set querySeriesEventIdsAsParticipant(Connection dbcon, int seriesId, long personId) throws SQLException { - FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, SQL_SELECT_PARTICIPANTS); - try { - fps.setSmallintU(1, seriesId); - fps.setIntegerU(2, personId); - - Set eventIds = new HashSet<>(); - fps.executeQuery().getFirstColumn(Long.class, eventIds); - return eventIds; - } finally { - fps.close(); - } - } - -} diff --git a/src/main/java/com/poststats/api/golf/service/impl/DatabaseEventService.java b/src/main/java/com/poststats/api/golf/service/impl/DatabaseEventService.java deleted file mode 100644 index 9452cba..0000000 --- a/src/main/java/com/poststats/api/golf/service/impl/DatabaseEventService.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.poststats.api.golf.service.impl; - -import java.sql.Connection; -import java.sql.SQLException; - -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Response.Status; - -import com.brianlong.sql.FlexPreparedStatement; -import com.poststats.api.golf.service.EventService; -import com.poststats.golf.sql.GolfSQL; -import com.poststats.sql.PostStatsDataSource; - -public class DatabaseEventService implements EventService { - - @Override - public int getSeriesId(long eventId) { - Connection dbcon = PostStatsDataSource.getInstance().acquire(true); - try { - return this.querySeriesId(dbcon, eventId); - } catch (SQLException se) { - throw new WebApplicationException("Database call failure", se, Status.INTERNAL_SERVER_ERROR); - } finally { - PostStatsDataSource.getInstance().release(dbcon); - } - } - - private int querySeriesId(Connection dbcon, long eventId) throws SQLException { - FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, GolfSQL.changeSchema("SELECT seriesId FROM ~g~.Event WHERE eventID=?")); - try { - fps.setIntegerU(1, eventId); - return fps.executeQuery().getOne(Integer.class); - } finally { - fps.close(); - } - } - -} diff --git a/src/main/java/com/poststats/golf/api/EventApi.java b/src/main/java/com/poststats/golf/api/EventApi.java new file mode 100644 index 0000000..dae01ea --- /dev/null +++ b/src/main/java/com/poststats/golf/api/EventApi.java @@ -0,0 +1,76 @@ +package com.poststats.golf.api; + +import com.brianlong.sql.DataSet; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.poststats.golf.api.model.Event; +import com.poststats.golf.api.model.EventDetail; +import com.poststats.golf.service.EventService; +import com.poststats.golf.transformer.EventTransformer; +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response.Status; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This API provides access to PostStats Golf Event meta-data and features. + * + * @author brian.long@poststats.com + */ +@RequestScoped +@Path("/event/{eventId}") +public class EventApi { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @PathParam("eventId") + private long eventId; + + @Inject + private EventService eventService; + + @Inject + private EventTransformer eventTransformer; + + @PostConstruct + public void init() { + this.logger.debug("EventApi init: {}", this.eventId); + } + + /** + * @return An event model object. + * @throws JsonProcessingException A JSON parsing issue occurred. + * @throws http-404 The specified event was not found. + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + public Event get() throws JsonProcessingException { + DataSet row = this.eventService.get(this.eventId); + if (row == null) throw new WebApplicationException("Event not found", Status.NOT_FOUND); + + return this.eventTransformer.toModel(row); + } + + /** + * @return An event model object. + * @throws JsonProcessingException A JSON parsing issue occurred. + * @throws http-404 The specified event was not found. + */ + @GET + @Path("/detail") + @Produces(MediaType.APPLICATION_JSON) + public EventDetail getDetail() throws JsonProcessingException { + DataSet row = this.eventService.getDetail(this.eventId); + if (row == null) throw new WebApplicationException("Event not found", Status.NOT_FOUND); + + return (EventDetail) this.eventTransformer.toModel(row, new EventDetail()); + } + +} diff --git a/src/main/java/com/poststats/api/golf/EventFinanceApi.java b/src/main/java/com/poststats/golf/api/EventFinanceApi.java similarity index 58% rename from src/main/java/com/poststats/api/golf/EventFinanceApi.java rename to src/main/java/com/poststats/golf/api/EventFinanceApi.java index e6a12bb..aa9c5f5 100644 --- a/src/main/java/com/poststats/api/golf/EventFinanceApi.java +++ b/src/main/java/com/poststats/golf/api/EventFinanceApi.java @@ -1,47 +1,48 @@ -package com.poststats.api.golf; +package com.poststats.golf.api; +import com.brianlong.sql.DataSet; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.poststats.golf.service.EventFinanceService; +import jakarta.annotation.security.RolesAllowed; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.SecurityContext; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.ServiceLoader; - -import javax.annotation.security.RolesAllowed; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.SecurityContext; - import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVPrinter; -import com.brianlong.sql.DataSet; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.poststats.api.golf.service.EventFinanceService; - +@RequestScoped @Path("/event/{eventId}/finance") public class EventFinanceApi { - + private final ObjectMapper mapper = new ObjectMapper(); - + @PathParam("eventId") private long eventId; - + + @Inject + private EventFinanceService eventFinanceService; + @GET @Path("/balance/persons") @Produces(MediaType.APPLICATION_JSON) @RolesAllowed("member") public String getBalanceByPersonsAsJson(@Context SecurityContext securityContext) throws JsonProcessingException { - if (!securityContext.isUserInRole(this.eventId + "~finance")) - throw new SecurityException("Not permitted"); - - List personsBalances = this.getEventFinanceService().getPersonsBalances(this.eventId); - + if (!securityContext.isUserInRole(this.eventId + "~finance")) throw new SecurityException("Not permitted"); + + List personsBalances = this.eventFinanceService.getPersonsBalances(this.eventId); + List> personsBalancesJson = new ArrayList<>(personsBalances.size()); for (DataSet personBalance : personsBalances) { Map personBalanceJson = new HashMap<>(5); @@ -51,53 +52,36 @@ public class EventFinanceApi { personBalanceJson.put("balance", personBalance.getFloat("balance")); personsBalancesJson.add(personBalanceJson); } - + return this.mapper.writeValueAsString(personsBalancesJson); } - + @GET @Path("/balance/persons/csv") @Produces("text/csv") @RolesAllowed("member") public String getBalanceByPersonsAsCsv(@Context SecurityContext securityContext) throws IOException { - if (!securityContext.isUserInRole(this.eventId + "~finance")) - throw new SecurityException("Not permitted"); - - List personsBalances = this.getEventFinanceService().getPersonsBalances(this.eventId); - + if (!securityContext.isUserInRole(this.eventId + "~finance")) throw new SecurityException("Not permitted"); + + List personsBalances = this.eventFinanceService.getPersonsBalances(this.eventId); + StringBuilder personsBalancesCsvBuilder = new StringBuilder(); CSVPrinter personsBalancesCsvPrinter = new CSVPrinter(personsBalancesCsvBuilder, CSVFormat.DEFAULT); try { - personsBalancesCsvPrinter.printRecord( - "personID", - "lname", - "fname", - "suffix", - "expense", - "paid", - "balance"); - + personsBalancesCsvPrinter.printRecord("personID", "lname", "fname", "suffix", "expense", "paid", "balance"); + for (DataSet personBalance : personsBalances) { - personsBalancesCsvPrinter.printRecord( - personBalance.getLong("personID"), - personBalance.getString("lname"), - personBalance.getString("fname"), - personBalance.getString("suffix"), - personBalance.getFloat("expense"), - personBalance.getFloat("paid"), + personsBalancesCsvPrinter.printRecord(personBalance.getLong("personID"), personBalance.getString("lname"), personBalance.getString("fname"), + personBalance.getString("suffix"), personBalance.getFloat("expense"), personBalance.getFloat("paid"), personBalance.getFloat("balance")); } - + personsBalancesCsvPrinter.flush(); } finally { personsBalancesCsvPrinter.close(); } - + return personsBalancesCsvBuilder.toString(); } - - private EventFinanceService getEventFinanceService() { - return ServiceLoader.load(EventFinanceService.class).iterator().next(); - } } diff --git a/src/main/java/com/poststats/api/golf/EventPersonApi.java b/src/main/java/com/poststats/golf/api/EventPersonApi.java similarity index 52% rename from src/main/java/com/poststats/api/golf/EventPersonApi.java rename to src/main/java/com/poststats/golf/api/EventPersonApi.java index 93e5152..d319167 100644 --- a/src/main/java/com/poststats/api/golf/EventPersonApi.java +++ b/src/main/java/com/poststats/golf/api/EventPersonApi.java @@ -1,5 +1,22 @@ -package com.poststats.api.golf; +package com.poststats.golf.api; +import com.brianlong.sql.DataSet; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.poststats.golf.service.EventPersonService; +import com.poststats.golf.service.EventService; +import com.poststats.security.Person; +import jakarta.annotation.security.RolesAllowed; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.SecurityContext; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; @@ -7,100 +24,86 @@ import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.ServiceLoader; import java.util.Set; - -import javax.annotation.security.RolesAllowed; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.SecurityContext; - import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVPrinter; -import com.brianlong.sql.DataSet; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.poststats.api.golf.service.EventPersonService; -import com.poststats.api.golf.service.EventService; -import com.poststats.api.model.Person; - +@RequestScoped @Path("/event/{eventId}") public class EventPersonApi { - + private final ObjectMapper mapper = new ObjectMapper(); - + @PathParam("eventId") private long eventId; - + + @Inject + private EventService eventService; + + @Inject + private EventPersonService eventPersonService; + @GET @Path("/people") - @Produces({MediaType.APPLICATION_JSON, "text/csv"}) + @Produces({ MediaType.APPLICATION_JSON, "text/csv" }) @RolesAllowed("member") public String get(@Context SecurityContext securityContext, @QueryParam("format") String format) throws JsonProcessingException, IOException { - if (!securityContext.isUserInRole(this.eventId + "~member")) - throw new SecurityException("Not permitted"); - - List persons = this.getEventPersonService().getPeople(this.eventId); - - if ("csv".equals(format)) { - return this.toAddressBookAsCsv(persons); - } else { - return this.toAddressBookAsJson(persons); - } - } - - @GET - @Path("/participants") - @Produces({MediaType.APPLICATION_JSON, "text/csv"}) - @RolesAllowed("member") - public String getParticipants(@Context SecurityContext securityContext, @QueryParam("format") String format) throws JsonProcessingException, IOException { - if (!securityContext.isUserInRole(this.eventId + "~member")) - throw new SecurityException("Not permitted"); - - List persons = this.getEventPersonService().getParticipants(this.eventId); - - if ("csv".equals(format)) { - return this.toAddressBookAsCsv(persons); - } else { - return this.toAddressBookAsJson(persons); - } - } - - @GET - @Path("/participants") - @Produces({MediaType.APPLICATION_JSON, "text/csv"}) - @RolesAllowed("member") - public String getSeriesParticipants(@Context SecurityContext securityContext, @QueryParam("format") String format) throws JsonProcessingException, IOException { - if (!securityContext.isUserInRole(this.eventId + "~member")) - throw new SecurityException("Not permitted"); - - int seriesId = this.getEventService().getSeriesId(this.eventId); + if (!securityContext.isUserInRole(this.eventId + "~member")) throw new SecurityException("Not permitted"); + + List persons = this.eventPersonService.getPeople(this.eventId); + + if ("csv".equals(format)) { + return this.toAddressBookAsCsv(persons); + } else { + return this.toAddressBookAsJson(persons); + } + } + + @GET + @Path("/participants") + @Produces({ MediaType.APPLICATION_JSON, "text/csv" }) + @RolesAllowed("member") + public String getParticipants(@Context SecurityContext securityContext, @Context @QueryParam("format") String format) + throws JsonProcessingException, IOException { + if (!securityContext.isUserInRole(this.eventId + "~member")) throw new SecurityException("Not permitted"); + + List persons = this.eventPersonService.getParticipants(this.eventId); + + if ("csv".equals(format)) { + return this.toAddressBookAsCsv(persons); + } else { + return this.toAddressBookAsJson(persons); + } + } + + @GET + @Path("/participants") + @Produces({ MediaType.APPLICATION_JSON, "text/csv" }) + @RolesAllowed("member") + public String getSeriesParticipants(@Context SecurityContext securityContext, @QueryParam("format") String format) + throws JsonProcessingException, IOException { + if (!securityContext.isUserInRole(this.eventId + "~member")) throw new SecurityException("Not permitted"); + + int seriesId = this.eventService.getSeriesId(this.eventId); + + Person principal = (Person) securityContext.getUserPrincipal(); + Set eventIds = this.eventPersonService.getSeriesEventIdsAsParticipant(seriesId, principal.getId()); - Person principal = (Person)securityContext.getUserPrincipal(); - Set eventIds = this.getEventPersonService().getSeriesEventIdsAsParticipant(seriesId, principal.getId()); - Set personIds = new HashSet<>(); List persons = new LinkedList<>(); for (long eventId : eventIds) { - List tmpPersons = this.getEventPersonService().getParticipants(eventId); + List tmpPersons = this.eventPersonService.getParticipants(eventId); for (DataSet person : tmpPersons) - if (personIds.add(person.getLong("personID"))) - persons.add(person); + if (personIds.add(person.getLong("personID"))) persons.add(person); } - + if ("csv".equals(format)) { return this.toAddressBookAsCsv(persons); } else { return this.toAddressBookAsJson(persons); } } - + private String toAddressBookAsJson(List persons) throws JsonProcessingException { List> personsJson = new ArrayList<>(persons.size()); for (DataSet person : persons) { @@ -113,46 +116,27 @@ public class EventPersonApi { personJson.put("emailAddress", person.getString("email")); personsJson.add(personJson); } - + return this.mapper.writeValueAsString(personsJson); } - + private String toAddressBookAsCsv(List persons) throws IOException { StringBuilder personsCsvBuilder = new StringBuilder(); CSVPrinter personsCsvPrinter = new CSVPrinter(personsCsvBuilder, CSVFormat.DEFAULT); try { - personsCsvPrinter.printRecord( - "ID", - "Prefix", - "Last Name", - "First Name", - "Suffix", - "Email Address"); - + personsCsvPrinter.printRecord("ID", "Prefix", "Last Name", "First Name", "Suffix", "Email Address"); + for (DataSet person : persons) { - personsCsvPrinter.printRecord( - person.getLong("personID"), - person.getString("prefix"), - person.getString("lname"), - person.getString("fname"), - person.getString("suffix"), - person.getString("email")); + personsCsvPrinter.printRecord(person.getLong("personID"), person.getString("prefix"), person.getString("lname"), person.getString("fname"), + person.getString("suffix"), person.getString("email")); } - + personsCsvPrinter.flush(); } finally { personsCsvPrinter.close(); } - + return personsCsvBuilder.toString(); } - - private EventService getEventService() { - return ServiceLoader.load(EventService.class).iterator().next(); - } - - private EventPersonService getEventPersonService() { - return ServiceLoader.load(EventPersonService.class).iterator().next(); - } } diff --git a/src/main/java/com/poststats/golf/api/GolferApi.java b/src/main/java/com/poststats/golf/api/GolferApi.java new file mode 100644 index 0000000..2924a03 --- /dev/null +++ b/src/main/java/com/poststats/golf/api/GolferApi.java @@ -0,0 +1,60 @@ +package com.poststats.golf.api; + +import com.brianlong.sql.DataSet; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.poststats.api.model.Person; +import com.poststats.golf.transformer.GolferTransformer; +import com.poststats.service.PersonService; +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response.Status; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This API provides access to PostStats Golfer meta-data and features. + * + * @author brian.long@poststats.com + */ +@RequestScoped +@Path("/golfer/{personId}") +public class GolferApi { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @PathParam("personId") + private long personId; + + @Inject + private PersonService personService; + + @Inject + private GolferTransformer golferTransformer; + + @PostConstruct + public void init() { + this.logger.debug("GolferApi init: {}", this.personId); + } + + /** + * @return An person model object. + * @throws JsonProcessingException A JSON parsing issue occurred. + * @throws http-404 The specified event was not found. + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + public Person get() throws JsonProcessingException { + DataSet row = this.personService.get(this.personId); + if (row == null) throw new WebApplicationException("Event not found", Status.NOT_FOUND); + + return this.golferTransformer.toModel(row); + } + +} diff --git a/src/main/java/com/poststats/golf/api/SeriesApi.java b/src/main/java/com/poststats/golf/api/SeriesApi.java new file mode 100644 index 0000000..3e48e73 --- /dev/null +++ b/src/main/java/com/poststats/golf/api/SeriesApi.java @@ -0,0 +1,113 @@ +package com.poststats.golf.api; + +import com.brianlong.sql.DataSet; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.poststats.golf.api.model.Event; +import com.poststats.golf.api.model.Series; +import com.poststats.golf.service.EventService; +import com.poststats.golf.service.SeriesService; +import com.poststats.golf.transformer.EventTransformer; +import com.poststats.golf.transformer.SeriesTransformer; +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response.Status; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This API provides access to PostStats Golf Event Series meta-data and + * features. + * + * @author brian.long@poststats.com + */ +@RequestScoped +@Path("/series/{seriesId}") +public class SeriesApi { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @PathParam("seriesId") + private int seriesId; + + @Inject + private SeriesService seriesService; + + @Inject + private EventService eventService; + + @Inject + private SeriesTransformer seriesTransformer; + + @Inject + private EventTransformer eventTransformer; + + @PostConstruct + public void init() { + this.logger.debug("SeriesApi init: {}", this.seriesId); + } + + /** + * @return An event series model object. + * @throws JsonProcessingException A JSON parsing issue occurred. + * @throws http-404 The specified series was not found. + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + public Series get() throws JsonProcessingException { + DataSet row = this.seriesService.get(this.seriesId); + if (row == null) throw new WebApplicationException("Series not found", Status.NOT_FOUND); + + return this.seriesTransformer.toModel(row); + } + + /** + * @return An event series model object. + * @throws JsonProcessingException A JSON parsing issue occurred. + * @throws http-404 The specified series was not found or it had + * no associated events. + */ + @GET + @Path("/eventIds") + @Produces(MediaType.APPLICATION_JSON) + public Set getEventIds() throws JsonProcessingException { + Set eventIds = this.eventService.getIds(this.seriesId); + if (eventIds.isEmpty()) throw new WebApplicationException("Series or events not found", Status.NOT_FOUND); + return eventIds; + } + + /** + * @param reverse `true` to sort events in reverse chronological order; `false` + * (default) otherwise. + * @return A list of event model objects. + * @throws JsonProcessingException A JSON parsing issue occurred. + * @throws http-404 The specified series was not found or it had + * no associated events. + */ + @GET + @Path("/events") + @Produces(MediaType.APPLICATION_JSON) + public List getEvents(@QueryParam("reverse") Boolean reverse) throws JsonProcessingException { + Map rows = this.eventService.get(this.seriesId, !Boolean.TRUE.equals(reverse)); + if (rows.isEmpty()) throw new WebApplicationException("Series or events not found", Status.NOT_FOUND); + + List events = new LinkedList(); + for (DataSet row : rows.values()) { + events.add(this.eventTransformer.toModel(row)); + } + + return events; + } + +} diff --git a/src/main/java/com/poststats/api/golf/VersionApi.java b/src/main/java/com/poststats/golf/api/VersionApi.java similarity index 74% rename from src/main/java/com/poststats/api/golf/VersionApi.java rename to src/main/java/com/poststats/golf/api/VersionApi.java index d6aae92..f2ef32b 100644 --- a/src/main/java/com/poststats/api/golf/VersionApi.java +++ b/src/main/java/com/poststats/golf/api/VersionApi.java @@ -1,26 +1,27 @@ -package com.poststats.api.golf; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; +package com.poststats.golf.api; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.TextNode; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +@ApplicationScoped @Path("/version") public class VersionApi { - + private ObjectMapper mapper = new ObjectMapper(); - + @GET @Produces(MediaType.APPLICATION_JSON) public String get() throws JsonProcessingException { // FIXME make dynamic return this.mapper.writeValueAsString(new TextNode("1.0")); } - + @GET @Path("/pattern") @Produces(MediaType.APPLICATION_JSON) diff --git a/src/main/java/com/poststats/golf/api/model/Event.java b/src/main/java/com/poststats/golf/api/model/Event.java new file mode 100644 index 0000000..72f7183 --- /dev/null +++ b/src/main/java/com/poststats/golf/api/model/Event.java @@ -0,0 +1,126 @@ +package com.poststats.golf.api.model; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.annotation.Generated; +import java.time.LocalDate; + +/** + * @author brian.long@poststats.com + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class Event { + + @JsonProperty(required = true) + private long id; + @JsonProperty(required = true) + private String name; + @JsonProperty + private String location; + @JsonProperty + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "YYYY-MM-dd") + private LocalDate liveline; + @JsonProperty + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "YYYY-MM-dd") + private LocalDate deadline; + @JsonProperty + private int seriesId; + + @Generated("Eclipse") + public long getId() { + return id; + } + + @Generated("Eclipse") + public void setId(long id) { + this.id = id; + } + + @Generated("Eclipse") + public String getName() { + return name; + } + + @Generated("Eclipse") + public void setName(String name) { + this.name = name; + } + + @Generated("Eclipse") + public String getLocation() { + return location; + } + + @Generated("Eclipse") + public void setLocation(String location) { + this.location = location; + } + + @Generated("Eclipse") + public LocalDate getLiveline() { + return liveline; + } + + @Generated("Eclipse") + public void setLiveline(LocalDate liveline) { + this.liveline = liveline; + } + + @Generated("Eclipse") + public LocalDate getDeadline() { + return deadline; + } + + @Generated("Eclipse") + public void setDeadline(LocalDate deadline) { + this.deadline = deadline; + } + + @Generated("Eclipse") + public int getSeriesId() { + return seriesId; + } + + @Generated("Eclipse") + public void setSeriesId(int seriesId) { + this.seriesId = seriesId; + } + + @Generated("Spark") + public Event withId(long id) { + this.id = id; + return this; + } + + @Generated("Spark") + public Event withName(String name) { + this.name = name; + return this; + } + + @Generated("Spark") + public Event withLocation(String location) { + this.location = location; + return this; + } + + @Generated("Spark") + public Event withLiveline(LocalDate liveline) { + this.liveline = liveline; + return this; + } + + @Generated("Spark") + public Event withDeadline(LocalDate deadline) { + this.deadline = deadline; + return this; + } + + @Generated("Spark") + public Event withSeriesId(int seriesId) { + this.seriesId = seriesId; + return this; + } + +} diff --git a/src/main/java/com/poststats/golf/api/model/EventDetail.java b/src/main/java/com/poststats/golf/api/model/EventDetail.java new file mode 100644 index 0000000..4c0054f --- /dev/null +++ b/src/main/java/com/poststats/golf/api/model/EventDetail.java @@ -0,0 +1,11 @@ +package com.poststats.golf.api.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +/** + * @author brian.long@poststats.com + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class EventDetail extends Event { + +} diff --git a/src/main/java/com/poststats/golf/api/model/Series.java b/src/main/java/com/poststats/golf/api/model/Series.java new file mode 100644 index 0000000..d1e4ad6 --- /dev/null +++ b/src/main/java/com/poststats/golf/api/model/Series.java @@ -0,0 +1,50 @@ +package com.poststats.golf.api.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.annotation.Generated; + +/** + * @author brian.long@poststats.com + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class Series { + + @JsonProperty(required = true) + private long id; + @JsonProperty(required = true) + private String name; + + @Generated("Eclipse") + public long getId() { + return id; + } + + @Generated("Eclipse") + public void setId(long id) { + this.id = id; + } + + @Generated("Eclipse") + public String getName() { + return name; + } + + @Generated("Eclipse") + public void setName(String name) { + this.name = name; + } + + @Generated("Spark") + public Series withId(long id) { + this.id = id; + return this; + } + + @Generated("Spark") + public Series withName(String name) { + this.name = name; + return this; + } + +} diff --git a/src/main/java/com/poststats/golf/package-info.java b/src/main/java/com/poststats/golf/package-info.java new file mode 100644 index 0000000..9e8915c --- /dev/null +++ b/src/main/java/com/poststats/golf/package-info.java @@ -0,0 +1,4 @@ +/** + * Here is a description. + */ +package com.poststats.golf; \ No newline at end of file diff --git a/src/main/java/com/poststats/golf/security/EventPersonSecurityContext.java b/src/main/java/com/poststats/golf/security/EventPersonSecurityContext.java new file mode 100644 index 0000000..e239b3a --- /dev/null +++ b/src/main/java/com/poststats/golf/security/EventPersonSecurityContext.java @@ -0,0 +1,38 @@ +package com.poststats.golf.security; + +import com.poststats.security.Person; +import jakarta.ws.rs.core.SecurityContext; +import java.security.Principal; + +public class EventPersonSecurityContext implements SecurityContext { + + private final SecurityContext securityContext; + private final long eventId; + + public EventPersonSecurityContext(SecurityContext securityContext, long eventId) { + this.securityContext = securityContext; + this.eventId = eventId; + } + + @Override + public Principal getUserPrincipal() { + return this.securityContext.getUserPrincipal(); + } + + @Override + public boolean isUserInRole(String role) { + Person person = (Person) this.securityContext.getUserPrincipal(); + return person.hasAccessControl(role, this.eventId); + } + + @Override + public String getAuthenticationScheme() { + return this.securityContext.getAuthenticationScheme(); + } + + @Override + public boolean isSecure() { + return this.securityContext.isSecure(); + } + +} diff --git a/src/main/java/com/poststats/api/golf/service/EventFinanceService.java b/src/main/java/com/poststats/golf/service/EventFinanceService.java similarity index 78% rename from src/main/java/com/poststats/api/golf/service/EventFinanceService.java rename to src/main/java/com/poststats/golf/service/EventFinanceService.java index 8e656d7..5956b95 100644 --- a/src/main/java/com/poststats/api/golf/service/EventFinanceService.java +++ b/src/main/java/com/poststats/golf/service/EventFinanceService.java @@ -1,11 +1,10 @@ -package com.poststats.api.golf.service; - -import java.util.List; +package com.poststats.golf.service; import com.brianlong.sql.DataSet; +import java.util.List; public interface EventFinanceService { - + List getPersonsBalances(long eventId); } diff --git a/src/main/java/com/poststats/api/golf/service/EventPersonService.java b/src/main/java/com/poststats/golf/service/EventPersonService.java similarity index 85% rename from src/main/java/com/poststats/api/golf/service/EventPersonService.java rename to src/main/java/com/poststats/golf/service/EventPersonService.java index 0bbc325..2df6d40 100644 --- a/src/main/java/com/poststats/api/golf/service/EventPersonService.java +++ b/src/main/java/com/poststats/golf/service/EventPersonService.java @@ -1,16 +1,15 @@ -package com.poststats.api.golf.service; +package com.poststats.golf.service; +import com.brianlong.sql.DataSet; import java.util.List; import java.util.Set; -import com.brianlong.sql.DataSet; - public interface EventPersonService { - + List getPeople(long eventId); - + List getParticipants(long eventId); - + Set getSeriesEventIdsAsParticipant(int seriesId, long personId); } diff --git a/src/main/java/com/poststats/golf/service/EventService.java b/src/main/java/com/poststats/golf/service/EventService.java new file mode 100644 index 0000000..fc1e4f4 --- /dev/null +++ b/src/main/java/com/poststats/golf/service/EventService.java @@ -0,0 +1,19 @@ +package com.poststats.golf.service; + +import com.brianlong.sql.DataSet; +import java.util.Map; +import java.util.Set; + +public interface EventService { + + DataSet get(long eventId); + + DataSet getDetail(long eventId); + + Map get(int seriesId, boolean chronological); + + Set getIds(int seriesId); + + int getSeriesId(long eventId); + +} diff --git a/src/main/java/com/poststats/api/golf/service/SeriesPersonService.java b/src/main/java/com/poststats/golf/service/SeriesPersonService.java similarity index 82% rename from src/main/java/com/poststats/api/golf/service/SeriesPersonService.java rename to src/main/java/com/poststats/golf/service/SeriesPersonService.java index 01abfd4..95f2852 100644 --- a/src/main/java/com/poststats/api/golf/service/SeriesPersonService.java +++ b/src/main/java/com/poststats/golf/service/SeriesPersonService.java @@ -1,13 +1,12 @@ -package com.poststats.api.golf.service; - -import java.util.List; +package com.poststats.golf.service; import com.brianlong.sql.DataSet; +import java.util.List; public interface SeriesPersonService { List getSeriesPeople(int seriesId); - + List getSeriesParticipants(int seriesId); } diff --git a/src/main/java/com/poststats/golf/service/SeriesService.java b/src/main/java/com/poststats/golf/service/SeriesService.java new file mode 100644 index 0000000..4104498 --- /dev/null +++ b/src/main/java/com/poststats/golf/service/SeriesService.java @@ -0,0 +1,11 @@ +package com.poststats.golf.service; + +import com.brianlong.sql.DataSet; + +public interface SeriesService { + + DataSet get(int seriesId); + + DataSet getByEventId(long eventId); + +} diff --git a/src/main/java/com/poststats/api/golf/service/impl/DatabaseEventFinanceService.java b/src/main/java/com/poststats/golf/service/db/EventFinanceServiceDAO.java similarity index 83% rename from src/main/java/com/poststats/api/golf/service/impl/DatabaseEventFinanceService.java rename to src/main/java/com/poststats/golf/service/db/EventFinanceServiceDAO.java index 76b244c..2ba2760 100644 --- a/src/main/java/com/poststats/api/golf/service/impl/DatabaseEventFinanceService.java +++ b/src/main/java/com/poststats/golf/service/db/EventFinanceServiceDAO.java @@ -1,45 +1,54 @@ -package com.poststats.api.golf.service.impl; +package com.poststats.golf.service.db; +import com.brianlong.sql.DataSet; +import com.brianlong.sql.FlexPreparedStatement; +import com.poststats.golf.service.EventFinanceService; +import com.poststats.golf.sql.GolfSQL; +import com.poststats.sql.PostStatsDataSource; +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response.Status; import java.sql.Connection; import java.sql.SQLException; import java.util.List; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Response.Status; +@ApplicationScoped +public class EventFinanceServiceDAO implements EventFinanceService { -import com.brianlong.sql.DataSet; -import com.brianlong.sql.FlexPreparedStatement; -import com.poststats.api.golf.service.EventFinanceService; -import com.poststats.golf.sql.GolfSQL; -import com.poststats.sql.PostStatsDataSource; + @PostConstruct + public void init() { + System.out.println("EventFinanceServiceDAO init"); + } -public class DatabaseEventFinanceService implements EventFinanceService { - @Override public List getPersonsBalances(long eventId) { - Connection dbcon = PostStatsDataSource.getInstance().acquire(true); + Connection dbcon = PostStatsDataSource.getInstance() + .acquire(true); try { return this.queryPersonsBalances(dbcon, eventId); } catch (SQLException se) { throw new WebApplicationException("Database call failure", se, Status.INTERNAL_SERVER_ERROR); } finally { - PostStatsDataSource.getInstance().release(dbcon); + PostStatsDataSource.getInstance() + .release(dbcon); } } - + private List queryPersonsBalances(Connection dbcon, long eventId) throws SQLException { FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, SQL_SELECT_BALANCES); try { for (int i = 1; i <= 5; i++) fps.setIntegerU(1, eventId); - return fps.executeQuery().getAllRows(); + return fps.executeQuery() + .getAllRows(); } finally { fps.close(); } } - - - + + + private static final String SQL_SELECT_BALANCES = GolfSQL.changeSchema(new StringBuilder() .append("SELECT P.personID, P.prefix, P.fname, P.lname, P.suffix, ") .append("TT.epersonID, SUM(TT.expenses) expenses, SUM(TT.paid) paid, (SUM(TT.paid)-SUM(TT.expenses)) balance ") diff --git a/src/main/java/com/poststats/golf/service/db/EventPersonServiceDAO.java b/src/main/java/com/poststats/golf/service/db/EventPersonServiceDAO.java new file mode 100644 index 0000000..5044efc --- /dev/null +++ b/src/main/java/com/poststats/golf/service/db/EventPersonServiceDAO.java @@ -0,0 +1,96 @@ +package com.poststats.golf.service.db; + +import com.brianlong.sql.DataSet; +import com.poststats.golf.service.EventPersonService; +import com.poststats.sql.PostStatsDataSource; +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response.Status; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.List; +import java.util.Set; + +@ApplicationScoped +public class EventPersonServiceDAO implements EventPersonService { + + @PostConstruct + public void init() { + System.out.println("EventFinanceServiceDAO init"); + } + + @Override + public List getPeople(long eventId) { + Connection dbcon = PostStatsDataSource.getInstance() + .acquire(true); + try { + return this.queryPersons(dbcon, eventId); + } catch (SQLException se) { + throw new WebApplicationException("Database call failure", se, Status.INTERNAL_SERVER_ERROR); + } finally { + PostStatsDataSource.getInstance() + .release(dbcon); + } + } + + @Override + public List getParticipants(long eventId) { + Connection dbcon = PostStatsDataSource.getInstance() + .acquire(true); + try { + return this.queryParticipants(dbcon, eventId); + } catch (SQLException se) { + throw new WebApplicationException("Database call failure", se, Status.INTERNAL_SERVER_ERROR); + } finally { + PostStatsDataSource.getInstance() + .release(dbcon); + } + } + + @Override + public Set getSeriesEventIdsAsParticipant(int seriesId, long personId) { + Connection dbcon = PostStatsDataSource.getInstance() + .acquire(true); + try { + return this.querySeriesEventIdsAsParticipant(dbcon, seriesId, personId); + } catch (SQLException se) { + throw new WebApplicationException("Database call failure", se, Status.INTERNAL_SERVER_ERROR); + } finally { + PostStatsDataSource.getInstance() + .release(dbcon); + } + } + + private List queryPersons(Connection dbcon, long eventId) throws SQLException { + throw new WebApplicationException(Status.NOT_IMPLEMENTED); + /* + * FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, + * SQL_SELECT_PERSONS); try { fps.setIntegerU(1, eventId); return + * fps.executeQuery().getAllRows(); } finally { fps.close(); } + */ + } + + private List queryParticipants(Connection dbcon, long eventId) throws SQLException { + throw new WebApplicationException(Status.NOT_IMPLEMENTED); + /* + * FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, + * SQL_SELECT_PARTICIPANTS); try { fps.setIntegerU(1, eventId); return + * fps.executeQuery().getAllRows(); } finally { fps.close(); } + */ + } + + private Set querySeriesEventIdsAsParticipant(Connection dbcon, int seriesId, long personId) throws SQLException { + throw new WebApplicationException(Status.NOT_IMPLEMENTED); + /* + * FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, + * SQL_SELECT_PARTICIPANTS); try { fps.setSmallintU(1, seriesId); + * fps.setIntegerU(2, personId); + * + * Set eventIds = new HashSet<>(); + * fps.executeQuery().getFirstColumn(Long.class, eventIds); return eventIds; } + * finally { fps.close(); } + */ + } + +} diff --git a/src/main/java/com/poststats/golf/service/db/EventServiceDAO.java b/src/main/java/com/poststats/golf/service/db/EventServiceDAO.java new file mode 100644 index 0000000..cd31242 --- /dev/null +++ b/src/main/java/com/poststats/golf/service/db/EventServiceDAO.java @@ -0,0 +1,170 @@ +package com.poststats.golf.service.db; + +import com.brianlong.sql.DataSet; +import com.brianlong.sql.FlexPreparedStatement; +import com.poststats.golf.service.EventService; +import com.poststats.golf.sql.GolfDataSource; +import com.poststats.golf.sql.GolfSQL; +import com.poststats.service.ServiceException; +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.ApplicationScoped; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ApplicationScoped +public class EventServiceDAO implements EventService { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @PostConstruct + public void init() { + this.logger.debug("EventFinanceServiceDAO init"); + } + + @Override + public DataSet get(long eventId) { + Connection dbcon = GolfDataSource.getInstance() + .acquire(true); + try { + return this.queryEvent(dbcon, eventId, false); + } catch (SQLException se) { + throw new ServiceException(se); + } finally { + GolfDataSource.getInstance() + .release(dbcon); + } + } + + @Override + public DataSet getDetail(long eventId) { + Connection dbcon = GolfDataSource.getInstance() + .acquire(true); + try { + return this.queryEvent(dbcon, eventId, true); + } catch (SQLException se) { + throw new ServiceException(se); + } finally { + GolfDataSource.getInstance() + .release(dbcon); + } + } + + @Override + public Map get(int seriesId, boolean chronological) { + Connection dbcon = GolfDataSource.getInstance() + .acquire(true); + try { + return this.queryEvents(dbcon, seriesId, chronological); + } catch (SQLException se) { + throw new ServiceException(se); + } finally { + GolfDataSource.getInstance() + .release(dbcon); + } + } + + @Override + public Set getIds(int seriesId) { + Connection dbcon = GolfDataSource.getInstance() + .acquire(true); + try { + return this.queryEventIds(dbcon, seriesId); + } catch (SQLException se) { + throw new ServiceException(se); + } finally { + GolfDataSource.getInstance() + .release(dbcon); + } + } + + @Override + public int getSeriesId(long eventId) { + Connection dbcon = GolfDataSource.getInstance() + .acquire(true); + try { + return this.querySeriesId(dbcon, eventId); + } catch (SQLException se) { + throw new ServiceException(se); + } finally { + GolfDataSource.getInstance() + .release(dbcon); + } + } + + private static final String SQL_SELECT_EVENT_BRIEF = GolfSQL.changeSchema( + "SELECT E.* " + + "FROM ~g~.Event E " + + "WHERE E.eventID=? "); + private static final String SQL_SELECT_EVENT_DETAIL = GolfSQL.changeSchema( + "SELECT E.*, EF.* " + + "FROM ~g~.Event E " + + " INNER JOIN ~g~.EventFeature EF ON (E.eventID=EF.eventID) " + + "WHERE E.eventID=? "); + + private DataSet queryEvent(Connection dbcon, long eventId, boolean includeExtraDetail) throws SQLException { + FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, includeExtraDetail ? SQL_SELECT_EVENT_DETAIL : SQL_SELECT_EVENT_BRIEF); + try { + fps.setIntegerU(1, eventId); + return fps.executeQuery() + .getNextRow(); + } finally { + fps.close(); + } + } + + private static final String SQL_SELECT_EVENTS = GolfSQL.changeSchema( + "SELECT E.* " + + "FROM ~g~.Event E " + + "WHERE E.seriesID=? "); + private static final String SQL_ORDER_EVENTS_ASC = "ORDER BY E.liveline ASC"; + private static final String SQL_ORDER_EVENTS_DESC = "ORDER BY E.liveline DESC"; + + private Map queryEvents(Connection dbcon, int seriesId, boolean chronological) throws SQLException { + FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, SQL_SELECT_EVENTS + (chronological ? SQL_ORDER_EVENTS_ASC : SQL_ORDER_EVENTS_DESC)); + try { + fps.setSmallintU(1, seriesId); + return fps.executeQuery() + .getAllRows("eventID", Long.class); + } finally { + fps.close(); + } + } + + private static final String SQL_SELECT_EVENT_IDS = GolfSQL.changeSchema( + "SELECT eventID FROM ~g~.Event WHERE seriesID=? "); + + private Set queryEventIds(Connection dbcon, int seriesId) throws SQLException { + Set eventIds = new HashSet<>(32); + + FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, SQL_SELECT_EVENT_IDS); + try { + fps.setSmallintU(1, seriesId); + fps.executeQuery() + .getFirstColumn(Long.class, eventIds); + } finally { + fps.close(); + } + + return eventIds; + } + + private static final String SQL_SELECT_SERIES_REF = GolfSQL.changeSchema( + "SELECT seriesID FROM ~g~.Event WHERE eventID=?"); + + private int querySeriesId(Connection dbcon, long eventId) throws SQLException { + FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, SQL_SELECT_SERIES_REF); + try { + fps.setIntegerU(1, eventId); + return fps.executeQuery() + .getOne(Integer.class); + } finally { + fps.close(); + } + } + +} diff --git a/src/main/java/com/poststats/golf/service/db/SeriesServiceDAO.java b/src/main/java/com/poststats/golf/service/db/SeriesServiceDAO.java new file mode 100644 index 0000000..84c389d --- /dev/null +++ b/src/main/java/com/poststats/golf/service/db/SeriesServiceDAO.java @@ -0,0 +1,82 @@ +package com.poststats.golf.service.db; + +import com.brianlong.sql.DataSet; +import com.brianlong.sql.FlexPreparedStatement; +import com.poststats.golf.service.SeriesService; +import com.poststats.golf.sql.GolfDataSource; +import com.poststats.golf.sql.GolfSQL; +import com.poststats.service.ServiceException; +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.ApplicationScoped; +import java.sql.Connection; +import java.sql.SQLException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ApplicationScoped +public class SeriesServiceDAO implements SeriesService { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @PostConstruct + public void init() { + this.logger.debug("SeriesServiceDAO init"); + } + + @Override + public DataSet get(int seriesId) { + Connection dbcon = GolfDataSource.getInstance() + .acquire(true); + try { + return this.querySeries(dbcon, seriesId); + } catch (SQLException se) { + throw new ServiceException(se); + } finally { + GolfDataSource.getInstance() + .release(dbcon); + } + } + + @Override + public DataSet getByEventId(long eventId) { + Connection dbcon = GolfDataSource.getInstance() + .acquire(true); + try { + return this.querySeries(dbcon, eventId); + } catch (SQLException se) { + throw new ServiceException(se); + } finally { + GolfDataSource.getInstance() + .release(dbcon); + } + } + + private static final String SQL_SELECT_SERIES = GolfSQL.changeSchema( + "SELECT * FROM ~g~.Series WHERE seriesID=? "); + + private DataSet querySeries(Connection dbcon, int seriesId) throws SQLException { + FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, SQL_SELECT_SERIES); + try { + fps.setSmallintU(1, seriesId); + return fps.executeQuery() + .getNextRow(); + } finally { + fps.close(); + } + } + + private static final String SQL_SELECT_SERIES_BY_EVENT_ID = GolfSQL.changeSchema( + "SELECT * FROM ~g~.Series WHERE eventID=? "); + + private DataSet querySeries(Connection dbcon, long eventId) throws SQLException { + FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, SQL_SELECT_SERIES_BY_EVENT_ID); + try { + fps.setIntegerU(1, eventId); + return fps.executeQuery() + .getNextRow(); + } finally { + fps.close(); + } + } + +} diff --git a/src/main/java/com/poststats/golf/servlet/EventFilter.java b/src/main/java/com/poststats/golf/servlet/EventFilter.java new file mode 100644 index 0000000..824ef50 --- /dev/null +++ b/src/main/java/com/poststats/golf/servlet/EventFilter.java @@ -0,0 +1,57 @@ +package com.poststats.golf.servlet; + +import com.brianlong.util.StringUtil; +import com.poststats.golf.Constants; +import com.poststats.golf.security.EventPersonSecurityContext; +import jakarta.annotation.Priority; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.ws.rs.Priorities; +import jakarta.ws.rs.container.ContainerRequestContext; +import jakarta.ws.rs.container.ContainerRequestFilter; +import jakarta.ws.rs.container.PreMatching; +import jakarta.ws.rs.core.SecurityContext; +import jakarta.ws.rs.ext.Provider; +import java.io.IOException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ApplicationScoped +@Provider +@PreMatching +@Priority(Priorities.AUTHORIZATION + 10) +public class EventFilter implements ContainerRequestFilter { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + String eventIdStr = requestContext.getUriInfo() + .getPathParameters() + .getFirst(Constants.EVENT_ID); + eventIdStr = StringUtil.getInstance() + .trim(eventIdStr); + + if (eventIdStr == null) { + eventIdStr = requestContext.getUriInfo() + .getQueryParameters() + .getFirst(Constants.EVENT_ID); + eventIdStr = StringUtil.getInstance() + .trim(eventIdStr); + } + + if (eventIdStr == null) return; + + this.logger.debug("Entering event context: {}", eventIdStr); + + long eventId = Long.valueOf(eventIdStr); + requestContext.setProperty(Constants.EVENT_ID, eventId); + + SecurityContext scontext = requestContext.getSecurityContext(); + if (scontext != null) { + this.logger.debug("Authorized for Event: {} => {}", scontext.getUserPrincipal() + .getName(), eventId); + requestContext.setSecurityContext(new EventPersonSecurityContext(scontext, eventId)); + } + } + +} diff --git a/src/main/java/com/poststats/golf/servlet/SeriesFilter.java b/src/main/java/com/poststats/golf/servlet/SeriesFilter.java new file mode 100644 index 0000000..bdbde6a --- /dev/null +++ b/src/main/java/com/poststats/golf/servlet/SeriesFilter.java @@ -0,0 +1,48 @@ +package com.poststats.golf.servlet; + +import com.brianlong.util.StringUtil; +import com.poststats.golf.Constants; +import jakarta.annotation.Priority; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.ws.rs.Priorities; +import jakarta.ws.rs.container.ContainerRequestContext; +import jakarta.ws.rs.container.ContainerRequestFilter; +import jakarta.ws.rs.container.PreMatching; +import jakarta.ws.rs.ext.Provider; +import java.io.IOException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ApplicationScoped +@Provider +@PreMatching +@Priority(Priorities.AUTHORIZATION + 5) +public class SeriesFilter implements ContainerRequestFilter { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + String seriesIdStr = requestContext.getUriInfo() + .getPathParameters() + .getFirst(Constants.EVENT_SERIES_ID); + seriesIdStr = StringUtil.getInstance() + .trim(seriesIdStr); + + if (seriesIdStr == null) { + seriesIdStr = requestContext.getUriInfo() + .getQueryParameters() + .getFirst(Constants.EVENT_SERIES_ID); + seriesIdStr = StringUtil.getInstance() + .trim(seriesIdStr); + } + + if (seriesIdStr == null) return; + + this.logger.debug("Entering series context: {}", seriesIdStr); + + int seriesId = Integer.valueOf(seriesIdStr); + requestContext.setProperty(Constants.EVENT_SERIES_ID, seriesId); + } + +} diff --git a/src/main/java/com/poststats/golf/transformer/EventTransformer.java b/src/main/java/com/poststats/golf/transformer/EventTransformer.java new file mode 100644 index 0000000..6b9beb0 --- /dev/null +++ b/src/main/java/com/poststats/golf/transformer/EventTransformer.java @@ -0,0 +1,41 @@ +package com.poststats.golf.transformer; + +import com.brianlong.sql.DataSet; +import com.poststats.golf.api.model.Event; +import com.poststats.transformer.Transformer; +import jakarta.enterprise.context.ApplicationScoped; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ApplicationScoped +public class EventTransformer implements Transformer { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Override + public Event toModel(DataSet row) { + return this.toModel(row, new Event()); + } + + @Override + public Event toModel(DataSet row, Event event) { + event.withId(row.getLong("eventID")) + .withName(row.getString("event")) + .withLiveline(row.getDate("liveline")) + .withDeadline(row.getDate("deadline")) + .withSeriesId(row.getInteger("seriesID")); + + StringBuilder location = new StringBuilder(); + if (row.isNotEmpty("addrcountry")) location.append(' ') + .append(row.getString("addrcountry")); + if (row.isNotEmpty("addrstate")) location.insert(0, ' ') + .insert(1, row.getString("addrstate")); + if (row.isNotEmpty("addrcity")) location.insert(0, ',') + .insert(0, row.getString("addrcity")); + this.logger.debug("Formulated event {} location: {}", row.getLong("eventID"), location); + event.setLocation(location.toString()); + + return event; + } + +} diff --git a/src/main/java/com/poststats/golf/transformer/GolferTransformer.java b/src/main/java/com/poststats/golf/transformer/GolferTransformer.java new file mode 100644 index 0000000..1cfa1eb --- /dev/null +++ b/src/main/java/com/poststats/golf/transformer/GolferTransformer.java @@ -0,0 +1,29 @@ +package com.poststats.golf.transformer; + +import com.brianlong.sql.DataSet; +import com.poststats.api.model.Person; +import com.poststats.transformer.Transformer; +import jakarta.enterprise.context.ApplicationScoped; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ApplicationScoped +public class GolferTransformer implements Transformer { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Override + public Person toModel(DataSet row) { + return this.toModel(row, new Person()); + } + + @Override + public Person toModel(DataSet row, Person person) { + person.withId(row.getLong("personID")) + .withFirstName(row.getString("fname")) + .withLastName(row.getString("lname")); + + return person; + } + +} diff --git a/src/main/java/com/poststats/golf/transformer/SeriesTransformer.java b/src/main/java/com/poststats/golf/transformer/SeriesTransformer.java new file mode 100644 index 0000000..737f2cf --- /dev/null +++ b/src/main/java/com/poststats/golf/transformer/SeriesTransformer.java @@ -0,0 +1,28 @@ +package com.poststats.golf.transformer; + +import com.brianlong.sql.DataSet; +import com.poststats.golf.api.model.Series; +import com.poststats.transformer.Transformer; +import jakarta.enterprise.context.ApplicationScoped; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ApplicationScoped +public class SeriesTransformer implements Transformer { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Override + public Series toModel(DataSet row) { + return this.toModel(row, new Series()); + } + + @Override + public Series toModel(DataSet row, Series series) { + series.withId(row.getInteger("seriesID")) + .withName(row.getString("series")); + + return series; + } + +} diff --git a/src/main/resources/META-INF/beans.xml b/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000..a50c2f8 --- /dev/null +++ b/src/main/resources/META-INF/beans.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/src/main/webapp/META-INF/com.poststats.api.golf.service.EventFinanceService b/src/main/webapp/META-INF/com.poststats.api.golf.service.EventFinanceService deleted file mode 100644 index 8fd585f..0000000 --- a/src/main/webapp/META-INF/com.poststats.api.golf.service.EventFinanceService +++ /dev/null @@ -1 +0,0 @@ -com.poststats.api.golf.service.impl.DatabaseEventFinanceService \ No newline at end of file diff --git a/src/main/webapp/META-INF/com.poststats.api.golf.service.EventPersonService b/src/main/webapp/META-INF/com.poststats.api.golf.service.EventPersonService deleted file mode 100644 index 292a79d..0000000 --- a/src/main/webapp/META-INF/com.poststats.api.golf.service.EventPersonService +++ /dev/null @@ -1 +0,0 @@ -com.poststats.api.golf.service.impl.DatabaseEventPersonService \ No newline at end of file diff --git a/src/main/webapp/META-INF/com.poststats.api.golf.service.EventService b/src/main/webapp/META-INF/com.poststats.api.golf.service.EventService deleted file mode 100644 index 400b4d9..0000000 --- a/src/main/webapp/META-INF/com.poststats.api.golf.service.EventService +++ /dev/null @@ -1 +0,0 @@ -com.poststats.api.golf.service.impl.DatabaseEventService \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 69dbbf0..0000000 --- a/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - PostStats Golf API - - - envConfig - /env-config.golf-api.properties - - - - 300 - - - - index.jsp - - - diff --git a/src/test/java/com/poststats/api/golf/VersionApiUnitTest.java b/src/test/java/com/poststats/golf/api/VersionApiUnitTest.java similarity index 62% rename from src/test/java/com/poststats/api/golf/VersionApiUnitTest.java rename to src/test/java/com/poststats/golf/api/VersionApiUnitTest.java index 7453e42..a142486 100644 --- a/src/test/java/com/poststats/api/golf/VersionApiUnitTest.java +++ b/src/test/java/com/poststats/golf/api/VersionApiUnitTest.java @@ -1,44 +1,45 @@ -package com.poststats.api.golf; +package com.poststats.golf.api; +import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.util.regex.Pattern; - import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import com.poststats.api.golf.VersionApi; - public class VersionApiUnitTest { - + + private static ObjectMapper om = new ObjectMapper(); private static VersionApi api; - + @BeforeClass public static void init() { api = new VersionApi(); } - + @Test public void get() throws IOException { String current = api.get(); Assert.assertNotNull(current); Assert.assertTrue(current.length() > 0); } - + @Test public void getPattern() throws IOException { String pattern = api.getRegexPattern(); Assert.assertNotNull(pattern); Assert.assertTrue(pattern.length() > 0); - Pattern.compile(pattern); + Pattern.compile(om.readValue(pattern, String.class)); } - + @Test public void isValidFormat() throws IOException { - String pattern = api.getRegexPattern(); - String current = api.get(); - Assert.assertTrue(Pattern.compile(pattern).matcher(current).matches()); + String pattern = om.readValue(api.getRegexPattern(), String.class); + String current = om.readValue(api.get(), String.class); + Assert.assertTrue(Pattern.compile(pattern) + .matcher(current) + .matches()); } } diff --git a/src/test/resources/log4j2.properties b/src/test/resources/log4j2.properties new file mode 100644 index 0000000..490c375 --- /dev/null +++ b/src/test/resources/log4j2.properties @@ -0,0 +1,19 @@ +rootLogger.level = debug +rootLogger.appenderRef.stdout.ref = api + +appender.rolling.type = RollingFile +appender.rolling.name = api +appender.rolling.fileName = ${catalina.base}/logs/api.log +appender.rolling.filePattern = ${catalina.base}/logs/api-%d{MM-dd-yyyy}.log.gz +appender.rolling.layout.type = PatternLayout +appender.rolling.layout.pattern = %d %p %C{1.} [%t] %m%n +appender.rolling.policies.type = Policies +appender.rolling.policies.time.type = TimeBasedTriggeringPolicy +appender.rolling.strategy.type = DefaultRolloverStrategy +appender.rolling.strategy.max = 10 + +logger.brianlong.name = com.brianlong +logger.brianlong.level = debug + +logger.poststats.name = com.poststats +logger.poststats.level = debug