diff --git a/pom.xml b/pom.xml index f3876c4..a64bdd2 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ io.github.oneteme.traceapi traceapi-core - 0.0.15-SNAPSHOT + 0.0.16-SNAPSHOT io.github.oneteme diff --git a/src/main/java/org/usf/trace/api/server/ApiController.java b/src/main/java/org/usf/trace/api/server/ApiController.java index 7ad8dc7..eb439a7 100644 --- a/src/main/java/org/usf/trace/api/server/ApiController.java +++ b/src/main/java/org/usf/trace/api/server/ApiController.java @@ -4,9 +4,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.http.ResponseEntity.accepted; import static org.usf.trace.api.server.Utils.requireSingle; -import static org.usf.traceapi.core.RemoteTraceSender.INCOMING_ENDPOINT; -import static org.usf.traceapi.core.RemoteTraceSender.MAIN_ENDPOINT; -import static org.usf.traceapi.core.RemoteTraceSender.TRACE_ENDPOINT; +import static org.usf.traceapi.core.Session.nextId; import java.time.Instant; import java.util.List; @@ -22,46 +20,52 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import org.usf.traceapi.core.ApiRequest; +import org.usf.traceapi.core.ApiSession; import org.usf.traceapi.core.ApplicationInfo; -import org.usf.traceapi.core.IncomingRequest; -import org.usf.traceapi.core.MainRequest; -import org.usf.traceapi.core.OutcomingRequest; +import org.usf.traceapi.core.MainSession; import org.usf.traceapi.core.Session; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +@Slf4j @CrossOrigin @RestController -@RequestMapping(value = TRACE_ENDPOINT, produces = APPLICATION_JSON_VALUE) +@RequestMapping(value = "trace", produces = APPLICATION_JSON_VALUE) @RequiredArgsConstructor -public class ApiController { +public class ApiController { private final RequestDao dao; private final SessionQueueService queueService; - @PutMapping(INCOMING_ENDPOINT) - public ResponseEntity saveRequest(@RequestBody IncomingRequest req) { - return appendRequest(req); + @PutMapping("session") + public ResponseEntity saveSession(HttpServletRequest hsr,@RequestBody Session[] sessions) { + for(Session s : sessions) { + if(isNull(s.getId())) { + if(s instanceof MainSession) { + s.setId(nextId()); // safe id set for web collectors + updateRemoteAddress(hsr,(MainSession) s); + } + else if(s instanceof ApiSession) { + log.warn("ApiSesstion id is null : {}", s); + } + } + } + queueService.add(sessions); + return accepted().build(); } - - @PutMapping(MAIN_ENDPOINT) - public ResponseEntity saveRequest(HttpServletRequest hsr, @RequestBody MainRequest req) { + public void updateRemoteAddress(HttpServletRequest hsr, @RequestBody MainSession req) { if(isNull(req.getApplication())) { //set IP address for WABAPP trace req.setApplication(new ApplicationInfo(null, null, hsr.getRemoteAddr(), null, null, null)); } else if(isNull(req.getApplication().getAddress())) { req.setApplication(req.getApplication().withAddress(hsr.getRemoteAddr())); } - return appendRequest(req); - } - - private ResponseEntity appendRequest(Session session){ - queueService.add(session); - return accepted().build(); } - @GetMapping(INCOMING_ENDPOINT) - public List getIncomingRequestByCriteria( + @GetMapping("incoming/request") + public List getIncomingRequestByCriteria( @RequestParam(defaultValue = "true", name = "lazy") boolean lazy, @RequestParam(required = false, name = "id") String[] id, @RequestParam(required = false, name = "name") String[] name, @@ -75,12 +79,12 @@ public List getIncomingRequestByCriteria( } @GetMapping("incoming/request/{id}") - public IncomingRequest getIncomingRequestById(@PathVariable String id) { // without tree + public ApiSession getIncomingRequestById(@PathVariable String id) { // without tree return requireSingle(dao.getIncomingRequestById(true, id)); } - @GetMapping(MAIN_ENDPOINT) - public List getMainRequestByCriteria( + @GetMapping("main/request") + public List getMainRequestByCriteria( @RequestParam(defaultValue = "true", name = "lazy") boolean lazy, @RequestParam(required = false, name = "id") String[] id, @RequestParam(required = false, name = "env") String[] env, @@ -93,17 +97,17 @@ public List getMainRequestByCriteria( } @GetMapping("main/request/{id}") - public MainRequest getMainRequestById(@PathVariable String id) { // without tree + public MainSession getMainRequestById(@PathVariable String id) { // without tree return requireSingle(dao.getMainRequestById(true, id)); } @GetMapping("incoming/request/{id}/out") - public OutcomingRequest getOutcomingRequestById(@PathVariable String id) { + public ApiRequest getOutcomingRequestById(@PathVariable String id) { return dao.getOutcomingRequestById(id); } @GetMapping("incoming/request/{id}/tree") //LATER - public IncomingRequest getIncomingRequestTreeById(@PathVariable String id) { + public ApiSession getIncomingRequestTreeById(@PathVariable String id) { return requireSingle(dao.getIncomingRequestById(true, id)); //change query } diff --git a/src/main/java/org/usf/trace/api/server/CacheController.java b/src/main/java/org/usf/trace/api/server/CacheController.java index 1326c29..02f6670 100644 --- a/src/main/java/org/usf/trace/api/server/CacheController.java +++ b/src/main/java/org/usf/trace/api/server/CacheController.java @@ -3,10 +3,13 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import java.util.Collection; +import java.util.Set; import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.usf.traceapi.core.Session; @@ -25,4 +28,9 @@ public Collection getCache(){ return queue.waitList(); } + @DeleteMapping + public Collection deleteSessions(@RequestParam("id") Set ids){ + return queue.deleteSessions(ids); + } + } \ No newline at end of file diff --git a/src/main/java/org/usf/trace/api/server/Exchange.java b/src/main/java/org/usf/trace/api/server/Exchange.java index 2059ee0..99ea5f7 100644 --- a/src/main/java/org/usf/trace/api/server/Exchange.java +++ b/src/main/java/org/usf/trace/api/server/Exchange.java @@ -1,8 +1,8 @@ package org.usf.trace.api.server; import lombok.Setter; -import org.usf.traceapi.core.IncomingRequest; -import org.usf.traceapi.core.OutcomingRequest; +import org.usf.traceapi.core.ApiSession; +import org.usf.traceapi.core.ApiRequest; import lombok.Getter; @@ -13,12 +13,8 @@ */ @Getter @Setter -public final class Exchange extends OutcomingRequest { +public final class Exchange extends ApiRequest { - private IncomingRequest remoteTrace; - - public Exchange(String id) { - super(id); - } + private ApiSession remoteTrace; } diff --git a/src/main/java/org/usf/trace/api/server/RequestDao.java b/src/main/java/org/usf/trace/api/server/RequestDao.java index 3ef32c7..8b2aeb2 100644 --- a/src/main/java/org/usf/trace/api/server/RequestDao.java +++ b/src/main/java/org/usf/trace/api/server/RequestDao.java @@ -21,6 +21,7 @@ import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Supplier; import java.util.stream.Stream; import org.springframework.jdbc.core.JdbcTemplate; @@ -43,13 +44,14 @@ public class RequestDao { @Transactional(rollbackFor = Exception.class) public void saveSessions(List sessions) { - filterAndSave(sessions, IncomingRequest.class, this::addIncomingRequest); - filterAndSave(sessions, MainRequest.class, this::addMainRequest); + filterAndSave(sessions, ApiSession.class, this::addIncomingRequest); + filterAndSave(sessions, MainSession.class, this::addMainRequest); filterSubAndSave(sessions, Session::getRequests, (s, r) -> new OutcomingRequestWrapper(r, s.getId()), this::addOutcomingRequest); filterSubAndSave(sessions, Session::getQueries, (s, q) -> new OutcomingQueryWrapper(q, s.getId()), this::addOutcomingQueries); + filterSubAndSave(sessions, Session::getStages, (s, st) -> new OutcomingStagesWrapper(st, s.getId()), this::addOutcomingStages); } - private void addMainRequest(List reqList) { + private void addMainRequest(List reqList) { template.batchUpdate("INSERT INTO E_MAIN_REQ(ID_MAIN_REQ,VA_NAME,VA_USR,DH_DBT,DH_FIN,LNCH,LOC,VA_THRED,VA_APP_NME,VA_VRS,VA_ADRS,VA_ENV,VA_OS,VA_RE,VA_ERR_CLS,VA_ERR_MSG)" + " VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", reqList, reqList.size(), (ps, o) -> { var app = nullableApplication(o.getApplication()); @@ -73,7 +75,7 @@ private void addMainRequest(List reqList) { }); } - private void addIncomingRequest(List reqList) { + private void addIncomingRequest(List reqList) { template.batchUpdate("INSERT INTO E_IN_REQ(ID_IN_REQ,VA_MTH,VA_PRTCL,VA_HST,CD_PRT,VA_PTH,VA_QRY,VA_CNT_TYP,VA_AUTH,CD_STT,VA_I_SZE,VA_O_SZE,DH_DBT,DH_FIN,VA_THRED,VA_ERR_CLS,VA_ERR_MSG,VA_API_NME,VA_USR,VA_APP_NME,VA_VRS,VA_ADRS,VA_ENV,VA_OS,VA_RE)" + " VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", reqList, reqList.size(), (ps, o) -> { var app = nullableApplication(o.getApplication()); @@ -131,6 +133,22 @@ private void addOutcomingRequest(List reqList) { }); } + public void addOutcomingStages(List stagesList){ + template.batchUpdate("INSERT INTO E_OUT_STG(VA_NAME,LOC,DH_DBT,DH_FIN,VA_USR,VA_THRED,VA_ERR_CLS,VA_ERR_MSG,CD_IN_REQ)" + + " VALUES(?,?,?,?,?,?,?,?,?)", stagesList,stagesList.size(),(ps,o)-> { + var exp = nullableException(o.getException()); + ps.setString(1,o.getName()); + ps.setString(2,o.getLocation()); + ps.setTimestamp(3,fromNullableInstant(o.getStart())); + ps.setTimestamp(4,fromNullableInstant(o.getEnd())); + ps.setString(5,o.getUser()); + ps.setString(6,o.getThreadName()); + ps.setString(7,exp.getClassname()); + ps.setString(8,exp.getMessage()); + ps.setString(9,o.getParentId()); + }); + } + private void addOutcomingQueries(List qryList) { var maxId = template.queryForObject("SELECT COALESCE(MAX(ID_OUT_QRY), 0) FROM E_OUT_QRY", Long.class); var inc = new AtomicLong(maxId); @@ -167,12 +185,13 @@ private void addDatabaseActions(List queries) { } @Deprecated // reuse RequestDao::outcomingRequests using criteria - public OutcomingRequest getOutcomingRequestById(String id) { + public ApiRequest getOutcomingRequestById(String id) { return template.query("SELECT ID_OUT_REQ,VA_PRTCL,VA_HST,CD_PRT,VA_PTH,VA_QRY,VA_MTH,CD_STT,VA_I_SZE,VA_O_SZE,DH_DBT,DH_FIN,VA_THRED,CD_IN_REQ FROM E_OUT_REQ" + " WHERE ID_OUT_REQ = ? ", new Object[]{id}, newArray(1, VARCHAR), rs -> { if (rs.next()) { - OutcomingRequest out = new OutcomingRequest(rs.getString("ID_OUT_REQ")); + ApiRequest out = new ApiRequest(); + out.setId(rs.getString("ID_OUT_REQ")); out.setProtocol(rs.getString("VA_PRTCL")); out.setHost(rs.getString("VA_HST")); out.setPort(rs.getInt("CD_PRT")); @@ -191,7 +210,7 @@ public OutcomingRequest getOutcomingRequestById(String id) { }); } - public List getMainRequestByCriteria(boolean lazy, FilterCriteria fc) { + public List getMainRequestByCriteria(boolean lazy, FilterCriteria fc) { var query = "SELECT ID_MAIN_REQ,VA_NAME,VA_USR,DH_DBT,DH_FIN,LNCH,LOC,VA_THRED,VA_APP_NME,VA_VRS,VA_ADRS,VA_ENV,VA_OS,VA_RE,VA_ERR_CLS,VA_ERR_MSG FROM E_MAIN_REQ"; Collection argTypes = new ArrayList<>(); @@ -199,8 +218,9 @@ public List getMainRequestByCriteria(boolean lazy, FilterCriteria f query += fc.toSql(ID_IN_REQ, ID_MAIN_REQ, VA_APP_NME, VA_ENV, CD_PRT, LNCH, DH_DBT, DH_FIN, args, argTypes); - List res = template.query(query, args.toArray(), argTypes.stream().mapToInt(i -> i).toArray(), (rs, i) -> { - MainRequest main = new MainRequest(rs.getString("ID_MAIN_REQ")); + List res = template.query(query, args.toArray(), argTypes.stream().mapToInt(i -> i).toArray(), (rs, i) -> { + MainSession main = new MainSession(); + main.setId(rs.getString("ID_MAIN_REQ")); // add value of nullable main.setName(rs.getString("VA_NAME")); main.setUser(rs.getString("VA_USR")); main.setStart(fromNullableTimestamp(rs.getTimestamp("DH_DBT"))); @@ -223,14 +243,15 @@ public List getMainRequestByCriteria(boolean lazy, FilterCriteria f return main; }); if (lazy && !res.isEmpty()) { - var reqMap = res.stream().collect(toMap(MainRequest::getId, identity())); - outcomingRequests(reqMap.keySet(),OutcomingRequest::new).forEach(r -> reqMap.get(r.getParentId()).getRequests().add(r.getRequest())); + var reqMap = res.stream().collect(toMap(MainSession::getId, identity())); + outcomingRequests(reqMap.keySet(),ApiRequest::new).forEach(r -> reqMap.get(r.getParentId()).getRequests().add(r.getRequest())); + outcomingStages(reqMap.keySet(),RunnableStage::new).forEach(r -> reqMap.get(r.getParentId()).getStages().add(r.getStage())); outcomingQueries(reqMap.keySet()).forEach(q -> reqMap.get(q.getParentId()).getQueries().add(q.getQuery())); } return res; } - public List getMainRequestById(boolean lazy, String... idArr) { + public List getMainRequestById(boolean lazy, String... idArr) { var query = "SELECT ID_MAIN_REQ,VA_NAME,VA_USR,DH_DBT,DH_FIN,LNCH,LOC,VA_THRED,VA_APP_NME,VA_VRS,VA_ADRS,VA_ENV,VA_OS,VA_RE,VA_ERR_CLS,VA_ERR_MSG FROM E_MAIN_REQ"; int[] argTypes = null; if (!isEmpty(idArr)) { @@ -238,8 +259,9 @@ public List getMainRequestById(boolean lazy, String... idArr) { argTypes = newArray(idArr.length, VARCHAR); } query += " order by DH_DBT desc"; - List res = template.query(query, idArr, argTypes, (rs, i) -> { - MainRequest main = new MainRequest(rs.getString("ID_MAIN_REQ")); + List res = template.query(query, idArr, argTypes, (rs, i) -> { + MainSession main = new MainSession(); + main.setId(rs.getString("ID_MAIN_REQ")); main.setName(rs.getString("VA_NAME")); main.setUser(rs.getString("VA_USR")); main.setStart(fromNullableTimestamp(rs.getTimestamp("DH_DBT"))); @@ -262,22 +284,24 @@ public List getMainRequestById(boolean lazy, String... idArr) { return main; }); if (lazy && !res.isEmpty()) { - var reqMap = res.stream().collect(toMap(MainRequest::getId, identity())); - outcomingRequests(reqMap.keySet(),OutcomingRequest::new).forEach(r -> reqMap.get(r.getParentId()).getRequests().add(r.getRequest())); + var reqMap = res.stream().collect(toMap(MainSession::getId, identity())); + outcomingRequests(reqMap.keySet(),ApiRequest::new).forEach(r -> reqMap.get(r.getParentId()).getRequests().add(r.getRequest())); + outcomingStages(reqMap.keySet(),RunnableStage::new).forEach(r -> reqMap.get(r.getParentId()).getStages().add(r.getStage())); outcomingQueries(reqMap.keySet()).forEach(q -> reqMap.get(q.getParentId()).getQueries().add(q.getQuery())); } return res; } - public List getIncomingRequestByCriteria(boolean lazy, FilterCriteria fs) { + public List getIncomingRequestByCriteria(boolean lazy, FilterCriteria fs) { var query = "SELECT ID_IN_REQ,VA_MTH,VA_PRTCL,VA_HST,CD_PRT,VA_PTH,VA_QRY,VA_CNT_TYP,VA_AUTH,CD_STT,VA_I_SZE,VA_O_SZE,DH_DBT,DH_FIN,VA_THRED,VA_ERR_CLS,VA_ERR_MSG,VA_API_NME,VA_USR,VA_APP_NME,VA_VRS,VA_ADRS,VA_ENV,VA_OS,VA_RE FROM E_IN_REQ "; Collection argTypes = new ArrayList<>(); Collection args = new ArrayList<>(); query += fs.toSql(ID_IN_REQ, ID_MAIN_REQ, VA_APP_NME, VA_ENV, CD_PRT, LNCH, DH_DBT, DH_FIN, args, argTypes); query += " order by DH_DBT desc"; - List res = template.query(query, args.toArray(), argTypes.stream().mapToInt(i -> i).toArray(), (rs, i) -> { - IncomingRequest in = new IncomingRequest(rs.getString("ID_IN_REQ")); + List res = template.query(query, args.toArray(), argTypes.stream().mapToInt(i -> i).toArray(), (rs, i) -> { + ApiSession in = new ApiSession(); + in.setId(rs.getString("ID_IN_REQ")); in.setMethod(rs.getString("VA_MTH")); in.setProtocol(rs.getString("VA_PRTCL")); in.setHost(rs.getString("VA_HST")); @@ -309,14 +333,15 @@ public List getIncomingRequestByCriteria(boolean lazy, FilterCr return in; }); if (lazy && !res.isEmpty()) { - var reqMap = res.stream().collect(toMap(IncomingRequest::getId, identity())); - outcomingRequests(reqMap.keySet(),OutcomingRequest::new).forEach(r -> reqMap.get(r.getParentId()).getRequests().add(r.getRequest())); + var reqMap = res.stream().collect(toMap(ApiSession::getId, identity())); + outcomingRequests(reqMap.keySet(),ApiRequest::new).forEach(r -> reqMap.get(r.getParentId()).getRequests().add(r.getRequest())); + outcomingStages(reqMap.keySet(),RunnableStage::new).forEach(r -> reqMap.get(r.getParentId()).getStages().add(r.getStage())); outcomingQueries(reqMap.keySet()).forEach(q -> reqMap.get(q.getParentId()).getQueries().add(q.getQuery())); } return res; } - public IncomingRequest getTreebyId(String id) { + public ApiSession getTreebyId(String id) { var query = " with recursive recusive(prnt,chld) as (" + " select ''::varchar as prnt, ? as chld " + " union all " + @@ -326,12 +351,12 @@ public IncomingRequest getTreebyId(String id) { ") select distinct(chld) from recusive"; List prntIds = template.query(query, (ResultSet rs, int rowNum) -> (rs.getString("chld")), id); - List prntIncList = getIncomingRequestById(true, Exchange::new,prntIds.toArray(String[]::new)); + List prntIncList = getIncomingRequestById(true, Exchange::new,prntIds.toArray(String[]::new)); prntIncList.forEach((prntA) -> { prntIncList.forEach((prntB) -> { if (!Objects.equals(prntA.getId(), prntB.getId())){ - Optional opt = prntB.getRequests().stream() + Optional opt = prntB.getRequests().stream() .filter(k -> prntA.getId().equals(k.getId())) .findFirst(); if (opt.isPresent()) { @@ -343,11 +368,11 @@ public IncomingRequest getTreebyId(String id) { }); return prntIncList.stream().filter(r -> r.getId().equals(id)).findAny().orElseThrow(); } - public List getIncomingRequestById(boolean lazy, String... idArr){ - return getIncomingRequestById( lazy, OutcomingRequest::new,idArr); + public List getIncomingRequestById(boolean lazy, String... idArr){ + return getIncomingRequestById( lazy, ApiRequest::new,idArr); } - public List getIncomingRequestById(boolean lazy, Function fn, String... idArr) { + public List getIncomingRequestById(boolean lazy, Supplier fn, String... idArr) { var query = "SELECT ID_IN_REQ,VA_MTH,VA_PRTCL,VA_HST,CD_PRT,VA_PTH,VA_QRY,VA_CNT_TYP,VA_AUTH,CD_STT,VA_I_SZE,VA_O_SZE,DH_DBT,DH_FIN,VA_THRED,VA_ERR_CLS,VA_ERR_MSG,VA_API_NME,VA_USR,VA_APP_NME,VA_VRS,VA_ADRS,VA_ENV,VA_OS,VA_RE FROM E_IN_REQ"; int[] argTypes = null; if (!isEmpty(idArr)) { @@ -355,8 +380,9 @@ public List getIncomingRequestById(boolean lazy, Function res = template.query(query, idArr, argTypes, (rs, i) -> { - IncomingRequest in = new IncomingRequest(rs.getString("ID_IN_REQ")); + List res = template.query(query, idArr, argTypes, (rs, i) -> { + ApiSession in = new ApiSession(); + in.setId(rs.getString("ID_IN_REQ")); in.setMethod(rs.getString("VA_MTH")); in.setProtocol(rs.getString("VA_PRTCL")); in.setHost(rs.getString("VA_HST")); @@ -388,18 +414,20 @@ public List getIncomingRequestById(boolean lazy, Function reqMap.get(r.getParentId()).getRequests().add(r.getRequest())); + outcomingStages(reqMap.keySet(),RunnableStage::new).forEach(r -> reqMap.get(r.getParentId()).getStages().add(r.getStage())); outcomingQueries(reqMap.keySet()).forEach(q -> reqMap.get(q.getParentId()).getQueries().add(q.getQuery())); } return res; } - public List outcomingRequests(Set incomingId, Function fn) { //use criteria + public List outcomingRequests(Set incomingId, Supplier fn) { //use criteria var query = "SELECT ID_OUT_REQ,VA_PRTCL,VA_HST,CD_PRT,VA_PTH,VA_QRY,VA_MTH,CD_STT,VA_I_SZE,VA_O_SZE,DH_DBT,DH_FIN,VA_THRED,VA_ERR_CLS,VA_ERR_MSG,CD_IN_REQ FROM E_OUT_REQ" + " WHERE CD_IN_REQ IN(" + nArg(incomingId.size()) + ") ORDER BY DH_DBT ASC"; return template.query(query, incomingId.toArray(), newArray(incomingId.size(), VARCHAR), (rs, i) -> { - OutcomingRequestWrapper out = new OutcomingRequestWrapper(rs.getString("ID_OUT_REQ"), rs.getString("CD_IN_REQ"), fn); + OutcomingRequestWrapper out = new OutcomingRequestWrapper(rs.getString("CD_IN_REQ"), fn); + out.setId(rs.getString("ID_OUT_REQ")); out.setProtocol(rs.getString("VA_PRTCL")); out.setHost(rs.getString("VA_HST")); out.setPort(rs.getInt("CD_PRT")); @@ -421,6 +449,24 @@ public List outcomingRequests(Set incomingId, F }); } + public List outcomingStages(Set sessionId, Supplier fn){ + var query = "SELECT VA_NAME,LOC,DH_DBT,DH_FIN,VA_USR,VA_THRED,VA_ERR_CLS,VA_ERR_MSG,CD_IN_REQ FROM E_OUT_STG" + +" WHERE CD_IN_REQ IN ("+ nArg(sessionId.size()) + ") ORDER BY DH_DBT"; + return template.query(query,sessionId.toArray(),newArray(sessionId.size(),VARCHAR),(rs,i)-> { + OutcomingStagesWrapper stg = new OutcomingStagesWrapper(rs.getString("CD_IN_REQ"),fn); + stg.setName(rs.getString("VA_NAME")); + stg.setLocation(rs.getString("LOC")); + stg.setStart(fromNullableTimestamp(rs.getTimestamp("DH_DBT"))); + stg.setEnd(fromNullableTimestamp(rs.getTimestamp("DH_FIN"))); + stg.setUser(rs.getString("VA_USR")); + stg.setException( new ExceptionInfo( + rs.getString("VA_ERR_CLS"), + rs.getString("VA_ERR_MSG") + )); + return stg; + }); + } + public List outcomingQueries(Set incomingId) { // non empty var query = "SELECT ID_OUT_QRY,VA_HST,CD_PRT,VA_SCHMA,DH_DBT,DH_FIN,VA_USR,VA_THRED,VA_DRV,VA_DB_NME,VA_DB_VRS,VA_CMPLT,CD_IN_REQ FROM E_OUT_QRY" + " WHERE CD_IN_REQ IN(" + nArg(incomingId.size()) + ")"; @@ -465,18 +511,38 @@ public List databaseActions(Set queries) { // non e class OutcomingRequestWrapper { @Delegate - private final OutcomingRequest request; + private final ApiRequest request; private final String parentId; - public OutcomingRequestWrapper(String id, String parentId, Function fn) { + public OutcomingRequestWrapper(String parentId, Supplier fn) { this.parentId = parentId; - this.request = fn.apply(id); //delegated setters + this.request = fn.get(); //delegated setters } - public OutcomingRequestWrapper(OutcomingRequest request, String parentId) { + public OutcomingRequestWrapper(ApiRequest request, String parentId) { this.parentId = parentId; this.request = request; //delegated getters } + + } + + @Getter + @Setter + class OutcomingStagesWrapper { + + @Delegate + private final RunnableStage stage; + private final String parentId; + + public OutcomingStagesWrapper(String parentId, Supplier fn){ + this.parentId = parentId; + this.stage = fn.get(); + } + + public OutcomingStagesWrapper(RunnableStage stage, String parentId){ + this.parentId = parentId; + this.stage = stage; + } } @Setter @@ -484,17 +550,17 @@ public OutcomingRequestWrapper(OutcomingRequest request, String parentId) { class OutcomingQueryWrapper { @Delegate - private final OutcomingQuery query; + private final DatabaseRequest query; private final String parentId; private long id; public OutcomingQueryWrapper(Long id, String parentId) { this.parentId = parentId; this.id = id; - this.query = new OutcomingQuery(); //delegated setters + this.query = new DatabaseRequest(); //delegated setters } - public OutcomingQueryWrapper(OutcomingQuery query, String parentId) { + public OutcomingQueryWrapper(DatabaseRequest query, String parentId) { this.parentId = parentId; this.query = query; //delegated getters } diff --git a/src/main/java/org/usf/trace/api/server/SessionQueueService.java b/src/main/java/org/usf/trace/api/server/SessionQueueService.java index e373bbd..f3d6660 100644 --- a/src/main/java/org/usf/trace/api/server/SessionQueueService.java +++ b/src/main/java/org/usf/trace/api/server/SessionQueueService.java @@ -1,11 +1,14 @@ package org.usf.trace.api.server; +import static java.util.Collections.addAll; import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; import static java.util.concurrent.TimeUnit.SECONDS; +import static java.util.stream.Collectors.toList; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; +import java.util.Set; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ScheduledExecutorService; @@ -33,8 +36,8 @@ public SessionQueueService(RequestDao dao, ScheduleProperties prop) { prop.getDelay()*2, prop.getDelay(), prop.getUnit()); //x2 wait for previous POD backup } - public void add(Session session) { - queue.add(session); + public void add(Session... sessions) { + addAll(queue, sessions); log.info("new request added to the queue : {} session(s)", queue.size()); } @@ -42,6 +45,12 @@ public Collection waitList(){ return new ArrayList<>(queue); // send copy } + public Collection deleteSessions(Set ids){ + var sessions = queue.stream().filter(s-> ids.contains(s.getId())).collect(toList()); + queue.removeAll(sessions); + return sessions; + } + private void safeBackup() { if(!queue.isEmpty()) { var list = new LinkedList(); diff --git a/src/main/java/org/usf/trace/api/server/TraceApiApplication.java b/src/main/java/org/usf/trace/api/server/TraceApiApplication.java index 5171bab..481872f 100644 --- a/src/main/java/org/usf/trace/api/server/TraceApiApplication.java +++ b/src/main/java/org/usf/trace/api/server/TraceApiApplication.java @@ -7,6 +7,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Primary; import org.springframework.transaction.annotation.EnableTransactionManagement; +import org.usf.traceapi.core.ApiSession; +import org.usf.traceapi.core.MainSession; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; @@ -23,8 +25,10 @@ public static void main(String[] args) { @Bean @Primary public ObjectMapper mapper(){ - return json() - .build() - .registerModules(new JavaTimeModule(), new ParameterNamesModule()); + var mapper = json() + .modules(new JavaTimeModule(), new ParameterNamesModule()) + .build(); + mapper.registerSubtypes(ApiSession.class, MainSession.class); + return mapper; } } diff --git a/src/main/java/org/usf/trace/api/server/TreeController.java b/src/main/java/org/usf/trace/api/server/TreeController.java index 99acc93..9d8b111 100644 --- a/src/main/java/org/usf/trace/api/server/TreeController.java +++ b/src/main/java/org/usf/trace/api/server/TreeController.java @@ -1,23 +1,27 @@ package org.usf.trace.api.server; -import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.*; -import org.usf.traceapi.core.IncomingRequest; - import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; -import static org.usf.traceapi.core.RemoteTraceSender.TRACE_ENDPOINT; + +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.usf.traceapi.core.ApiRequest; + +import lombok.RequiredArgsConstructor; @CrossOrigin @RestController -@RequestMapping(value = TRACE_ENDPOINT, produces = APPLICATION_JSON_VALUE) +@RequestMapping(value = "trace", produces = APPLICATION_JSON_VALUE) @RequiredArgsConstructor public class TreeController { private final RequestDao dao; @GetMapping("tree/request/{id}") - public IncomingRequest getTreebyId(@PathVariable String id){ + public ApiRequest getTreebyId(@PathVariable String id){ return dao.getTreebyId(id); } } diff --git a/src/main/java/org/usf/trace/api/server/config/DataConstants.java b/src/main/java/org/usf/trace/api/server/config/DataConstants.java index 84f4cb2..5d86874 100644 --- a/src/main/java/org/usf/trace/api/server/config/DataConstants.java +++ b/src/main/java/org/usf/trace/api/server/config/DataConstants.java @@ -20,103 +20,117 @@ public final class DataConstants { public static String sessionColumns(TraceApiColumn column) { switch (column) { - case ID: return "id_main_req"; - case NAME: return "va_name"; - case START: return "dh_dbt"; - case END: return "dh_fin"; - case USER: return "va_usr"; - case OS: return "va_os"; - case RE: return "va_re"; - case TYPE: return "lnch"; - case LOCATION: return "loc"; - case THREAD: return "va_thred"; - case APP_NAME: return "va_app_nme"; - case VERSION: return "va_vrs"; - case ADDRESS: return "va_adrs"; - case ENVIRONEMENT: return "va_env"; - case ERR_TYPE: return "va_err_cls"; - case ERR_MSG: return "va_err_msg"; + case ID: return "ID_MAIN_REQ"; + case NAME: return "VA_NAME"; + case START: return "DH_DBT"; + case END: return "DH_FIN"; + case USER: return "VA_USR"; + case OS: return "VA_OS"; + case RE: return "VA_RE"; + case TYPE: return "LNCH"; + case LOCATION: return "LOC"; + case THREAD: return "VA_THRED"; + case APP_NAME: return "VA_APP_NME"; + case VERSION: return "VA_VRS"; + case ADDRESS: return "VA_ADRS"; + case ENVIRONEMENT: return "VA_ENV"; + case ERR_TYPE: return "VA_ERR_CLS"; + case ERR_MSG: return "VA_ERR_MSG"; default: return null; } } public static String incReqColumns(TraceApiColumn column) { switch (column) { - case ID: return "id_in_req"; - case METHOD: return "va_mth"; - case PROTOCOL: return "va_prtcl"; - case HOST: return "va_hst"; - case PORT: return "cd_prt"; - case PATH: return "va_pth"; - case QUERY: return "va_qry"; - case MEDIA: return "va_cnt_typ"; - case AUTH: return "va_auth"; - case STATUS: return "cd_stt"; - case SIZE_IN: return "va_i_sze"; - case SIZE_OUT: return "va_o_sze"; - case START: return "dh_dbt"; - case END: return "dh_fin"; - case THREAD: return "va_thred"; - case API_NAME: return "va_api_nme"; - case USER: return "va_usr"; - case APP_NAME: return "va_app_nme"; - case VERSION: return "va_vrs"; - case ADDRESS: return "va_adrs"; - case ENVIRONEMENT: return "va_env"; - case OS: return "va_os"; - case RE: return "va_re"; + case ID: return "ID_IN_REQ"; + case METHOD: return "VA_MTH"; + case PROTOCOL: return "VA_PRTCL"; + case HOST: return "VA_HST"; + case PORT: return "CD_PRT"; + case PATH: return "VA_PTH"; + case QUERY: return "VA_QRY"; + case MEDIA: return "VA_CNT_TYP"; + case AUTH: return "VA_AUTH"; + case STATUS: return "CD_STT"; + case SIZE_IN: return "VA_I_SZE"; + case SIZE_OUT: return "VA_O_SZE"; + case START: return "DH_DBT"; + case END: return "DH_FIN"; + case THREAD: return "VA_THRED"; + case API_NAME: return "VA_API_NME"; + case USER: return "VA_USR"; + case APP_NAME: return "VA_APP_NME"; + case VERSION: return "VA_VRS"; + case ADDRESS: return "VA_ADRS"; + case ENVIRONEMENT: return "VA_ENV"; + case OS: return "VA_OS"; + case RE: return "VA_RE"; default: return null; } } public static String outReqColumns(TraceApiColumn column) { switch (column) { - case ID: return "id_out_req"; - case METHOD: return "va_mth"; - case PROTOCOL: return "va_prtcl"; - case HOST: return "va_hst"; - case PORT: return "cd_prt"; - case PATH: return "va_pth"; - case QUERY: return "va_qry"; - case MEDIA: return "va_cnt_typ"; - case AUTH: return "va_auth"; - case STATUS: return "cd_stt"; - case SIZE_IN: return "va_i_sze"; - case SIZE_OUT: return "va_o_sze"; - case START: return "dh_dbt"; - case END: return "dh_fin"; - case THREAD: return "va_thred"; - case PARENT: return "cd_in_req"; + case ID: return "ID_OUT_REQ"; + case METHOD: return "VA_MTH"; + case PROTOCOL: return "VA_PRTCL"; + case HOST: return "VA_HST"; + case PORT: return "CD_PRT"; + case PATH: return "VA_PTH"; + case QUERY: return "VA_QRY"; + case MEDIA: return "VA_CNT_TYP"; + case AUTH: return "VA_AUTH"; + case STATUS: return "CD_STT"; + case SIZE_IN: return "VA_I_SZE"; + case SIZE_OUT: return "VA_O_SZE"; + case START: return "DH_DBT"; + case END: return "DH_FIN"; + case THREAD: return "VA_THRED"; + case PARENT: return "CD_IN_REQ"; default: return null; } } public static String outQryColumns(TraceApiColumn column) { switch (column){ - case ID: return "id_out_qry"; - case HOST: return "va_hst"; - case PORT: return "cd_prt"; - case SCHEMA: return "va_schma"; - case START: return "dh_dbt"; - case END: return "dh_fin"; - case USER: return "va_usr"; - case THREAD: return "va_thred"; - case DRIVER: return "va_drv"; - case DB_NAME: return "va_db_nme"; - case DB_VERSION: return "va_db_vrs"; - case COMPLETE: return "va_cmplt"; - case PARENT: return "cd_in_req"; + case ID: return "ID_OUT_QRY"; + case HOST: return "VA_HST"; + case PORT: return "CD_PRT"; + case SCHEMA: return "VA_SCHMA"; + case START: return "DH_DBT"; + case END: return "DH_FIN"; + case USER: return "VA_USR"; + case THREAD: return "VA_THRED"; + case DRIVER: return "VA_DRV"; + case DB_NAME: return "VA_DB_NME"; + case DB_VERSION: return "VA_DB_VRS"; + case COMPLETE: return "VA_CMPLT"; + case PARENT: return "CD_IN_REQ"; + default: return null; + } + } + + public static String outStgColumns(TraceApiColumn column) { + switch (column){ + case NAME: return "VA_NAME"; + case LOCATION: return "LOC"; + case START: return "DH_DBT"; + case END: return "DH_FIN"; + case USER: return "VA_USR"; + case THREAD: return "VA_THRED"; + case ERR_TYPE: return "VA_ERR_CLS"; + case ERR_MSG: return "VA_ERR_MSG"; default: return null; } } public static String dbActColumns(TraceApiColumn column){ switch (column){ - case TYPE: return"va_typ"; - case START: return "dh_dbt"; - case END: return "dh_fin"; - case ERR_TYPE: return "va_err_cls"; - case ERR_MSG: return "va_err_msg"; - case PARENT: return "cd_out_qry"; + case TYPE: return"VA_TYP"; + case START: return "DH_DBT"; + case END: return "DH_FIN"; + case ERR_TYPE: return "VA_ERR_CLS"; + case ERR_MSG: return "VA_ERR_MSG"; + case PARENT: return "CD_OUT_QRY"; default: return null; } } diff --git a/src/main/java/org/usf/trace/api/server/config/TraceApiTable.java b/src/main/java/org/usf/trace/api/server/config/TraceApiTable.java index 6dd0e28..0398324 100644 --- a/src/main/java/org/usf/trace/api/server/config/TraceApiTable.java +++ b/src/main/java/org/usf/trace/api/server/config/TraceApiTable.java @@ -14,11 +14,12 @@ @RequiredArgsConstructor public enum TraceApiTable implements TableDecorator { - OUT("e_out_req", DataConstants::outReqColumns), - REQUEST("e_in_req", DataConstants::incReqColumns), - SESSION("e_main_req", DataConstants::sessionColumns), - QUERY("e_out_qry",DataConstants::outQryColumns), - DBACTION("e_db_act",DataConstants::dbActColumns); + OUT("E_OUT_REQ", DataConstants::outReqColumns), + REQUEST("E_IN_REQ", DataConstants::incReqColumns), + SESSION("E_MAIN_REQ", DataConstants::sessionColumns), + QUERY("E_OUT_QRY",DataConstants::outQryColumns), + STAGES("E_OUT_STG",DataConstants::outStgColumns), + DBACTION("E_DB_ACT",DataConstants::dbActColumns); @NonNull private final String tableName; diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index 1501466..14be9f8 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -1,93 +1,105 @@ ---https://www.postgresql.org/docs/current/datatype-character.html -CREATE TABLE IF NOT EXISTS E_MAIN_REQ( - ID_MAIN_REQ VARCHAR PRIMARY KEY, - VA_NAME VARCHAR, - VA_USR VARCHAR, - DH_DBT TIMESTAMP(3), - DH_FIN TIMESTAMP(3), - LNCH VARCHAR, - LOC VARCHAR, - VA_THRED VARCHAR, - VA_APP_NME VARCHAR, - VA_VRS VARCHAR, - VA_ADRS VARCHAR, - VA_ENV VARCHAR, - VA_OS VARCHAR, - VA_RE VARCHAR, - VA_ERR_CLS VARCHAR, - VA_ERR_MSG VARCHAR + +CREATE TABLE IF NOT EXISTS E_MAIN_REQ ( + ID_MAIN_REQ VARCHAR PRIMARY KEY, + VA_NAME VARCHAR, + VA_USR VARCHAR, + DH_DBT TIMESTAMP(3), + DH_FIN TIMESTAMP(3), + LNCH VARCHAR, + LOC VARCHAR, + VA_THRED VARCHAR, + VA_APP_NME VARCHAR, + VA_VRS VARCHAR, + VA_ADRS VARCHAR, + VA_ENV VARCHAR, + VA_OS VARCHAR, + VA_RE VARCHAR, + VA_ERR_CLS VARCHAR, + VA_ERR_MSG VARCHAR ); CREATE TABLE IF NOT EXISTS E_IN_REQ ( - ID_IN_REQ VARCHAR PRIMARY KEY, - VA_MTH VARCHAR, - VA_PRTCL VARCHAR, - VA_HST VARCHAR, - CD_PRT INT, - VA_PTH VARCHAR, - VA_QRY VARCHAR, - VA_CNT_TYP VARCHAR, - VA_AUTH VARCHAR, - CD_STT INT, - VA_I_SZE BIGINT, - VA_O_SZE BIGINT, - DH_DBT TIMESTAMP(3), - DH_FIN TIMESTAMP(3), - VA_THRED VARCHAR, - VA_ERR_CLS VARCHAR, - VA_ERR_MSG VARCHAR, - VA_API_NME VARCHAR, - VA_USR VARCHAR, - VA_APP_NME VARCHAR, - VA_VRS VARCHAR, - VA_ADRS VARCHAR, - VA_ENV VARCHAR, - VA_OS VARCHAR, - VA_RE VARCHAR + ID_IN_REQ VARCHAR PRIMARY KEY, + VA_MTH VARCHAR, + VA_PRTCL VARCHAR, + VA_HST VARCHAR, + CD_PRT INT, + VA_PTH VARCHAR, + VA_QRY VARCHAR, + VA_CNT_TYP VARCHAR, + VA_AUTH VARCHAR, + CD_STT INT, + VA_I_SZE BIGINT, + VA_O_SZE BIGINT, + DH_DBT TIMESTAMP(3), + DH_FIN TIMESTAMP(3), + VA_THRED VARCHAR, + VA_ERR_CLS VARCHAR, + VA_ERR_MSG VARCHAR, + VA_API_NME VARCHAR, + VA_USR VARCHAR, + VA_APP_NME VARCHAR, + VA_VRS VARCHAR, + VA_ADRS VARCHAR, + VA_ENV VARCHAR, + VA_OS VARCHAR, + VA_RE VARCHAR ); CREATE TABLE IF NOT EXISTS E_OUT_REQ ( - ID_OUT_REQ VARCHAR PRIMARY KEY, - VA_MTH VARCHAR, - VA_PRTCL VARCHAR, - VA_HST VARCHAR, - CD_PRT INT, - VA_PTH VARCHAR, - VA_QRY VARCHAR, - VA_CNT_TYP VARCHAR, - VA_AUTH VARCHAR, - CD_STT INT, - VA_I_SZE BIGINT, - VA_O_SZE BIGINT, - DH_DBT TIMESTAMP(3), - DH_FIN TIMESTAMP(3), - VA_THRED VARCHAR, - VA_ERR_CLS VARCHAR, - VA_ERR_MSG VARCHAR, - CD_IN_REQ VARCHAR + ID_OUT_REQ VARCHAR, -- NULL + VA_MTH VARCHAR, + VA_PRTCL VARCHAR, + VA_HST VARCHAR, + CD_PRT INT, + VA_PTH VARCHAR, + VA_QRY VARCHAR, + VA_CNT_TYP VARCHAR, + VA_AUTH VARCHAR, + CD_STT INT, + VA_I_SZE BIGINT, + VA_O_SZE BIGINT, + DH_DBT TIMESTAMP(3), + DH_FIN TIMESTAMP(3), + VA_THRED VARCHAR, + VA_ERR_CLS VARCHAR, + VA_ERR_MSG VARCHAR, + CD_IN_REQ VARCHAR ); CREATE TABLE IF NOT EXISTS E_OUT_QRY ( - ID_OUT_QRY BIGINT, - VA_HST VARCHAR, - CD_PRT INT, - VA_SCHMA VARCHAR, + ID_OUT_QRY BIGINT, + VA_HST VARCHAR, + CD_PRT INT, + VA_SCHMA VARCHAR, + DH_DBT TIMESTAMP(3), + DH_FIN TIMESTAMP(3), + VA_USR VARCHAR, + VA_THRED VARCHAR, + VA_DRV VARCHAR, + VA_DB_NME VARCHAR, + VA_DB_VRS VARCHAR, + VA_CMPLT CHAR, + CD_IN_REQ VARCHAR +); + +CREATE TABLE IF NOT EXISTS E_OUT_STG ( + VA_NAME VARCHAR, + LOC VARCHAR, DH_DBT TIMESTAMP(3), DH_FIN TIMESTAMP(3), VA_USR VARCHAR, VA_THRED VARCHAR, - VA_DRV VARCHAR, - VA_DB_NME VARCHAR, - VA_DB_VRS VARCHAR, - VA_CMPLT CHAR, + VA_ERR_CLS VARCHAR, + VA_ERR_MSG VARCHAR, CD_IN_REQ VARCHAR ); -CREATE TABLE IF NOT EXISTS E_DB_ACT( - VA_TYP VARCHAR, - DH_DBT TIMESTAMP(3), - DH_FIN TIMESTAMP(3), - VA_ERR_CLS VARCHAR, - VA_ERR_MSG VARCHAR, - CD_OUT_QRY BIGINT +CREATE TABLE IF NOT EXISTS E_DB_ACT ( + VA_TYP VARCHAR, + DH_DBT TIMESTAMP(3), + DH_FIN TIMESTAMP(3), + VA_ERR_CLS VARCHAR, + VA_ERR_MSG VARCHAR, + CD_OUT_QRY BIGINT );