diff --git a/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/OpenDcsResource.java b/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/OpenDcsResource.java index d5a931a9..eeebd1c2 100644 --- a/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/OpenDcsResource.java +++ b/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/OpenDcsResource.java @@ -22,7 +22,10 @@ import javax.ws.rs.core.Context; import decodes.cwms.CwmsDatabaseProvider; +import decodes.db.Database; import decodes.db.DatabaseException; +import decodes.db.DatabaseIO; +import decodes.tsdb.TimeSeriesDb; import decodes.util.DecodesSettings; import opendcs.opentsdb.OpenTsdbProvider; import org.opendcs.database.DatabaseService; @@ -81,7 +84,18 @@ final OpenDcsDatabase createDb() { throw new IllegalStateException("Error connecting to the database via JNDI", ex); } -// throw new IllegalStateException("Error connecting to the database via JNDI", e); } } + + DatabaseIO getLegacyDatabase() + { + return createDb().getLegacyDatabase(Database.class).map(Database::getDbIo) + .orElseThrow(() -> new UnsupportedOperationException("Endpoint is unsupported by the OpenDCS REST API.")); + } + + TimeSeriesDb getLegacyTimeseriesDB() + { + return createDb().getLegacyDatabase(TimeSeriesDb.class) + .orElseThrow(() -> new UnsupportedOperationException("Endpoint is unsupported by the OpenDCS REST API.")); + } } diff --git a/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/RoutingResources.java b/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/RoutingResources.java index e7bc268e..0f14d86c 100644 --- a/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/RoutingResources.java +++ b/opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/RoutingResources.java @@ -15,11 +15,16 @@ package org.opendcs.odcsapi.res; -import java.sql.SQLException; -import java.util.logging.Logger; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.List; +import java.util.TimeZone; +import java.util.Vector; +import java.util.stream.Collectors; import javax.annotation.security.RolesAllowed; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -33,22 +38,36 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import decodes.db.DataSource; +import decodes.db.DatabaseException; +import decodes.db.DatabaseIO; +import decodes.db.RoutingSpec; +import decodes.db.RoutingSpecList; +import decodes.db.ScheduleEntry; +import decodes.db.ScheduleEntryStatus; +import decodes.polling.DacqEvent; +import decodes.sql.DbKey; +import decodes.tsdb.DbIoException; +import ilex.util.Logger; +import opendcs.dai.DacqEventDAI; +import opendcs.dai.ScheduleEntryDAI; +import org.opendcs.odcsapi.beans.ApiDacqEvent; import org.opendcs.odcsapi.beans.ApiRouting; +import org.opendcs.odcsapi.beans.ApiRoutingExecStatus; +import org.opendcs.odcsapi.beans.ApiRoutingRef; +import org.opendcs.odcsapi.beans.ApiRoutingStatus; import org.opendcs.odcsapi.beans.ApiScheduleEntry; -import org.opendcs.odcsapi.dao.ApiRoutingDAO; +import org.opendcs.odcsapi.beans.ApiScheduleEntryRef; import org.opendcs.odcsapi.dao.DbException; -import org.opendcs.odcsapi.errorhandling.ErrorCodes; import org.opendcs.odcsapi.errorhandling.WebAppException; -import org.opendcs.odcsapi.hydrojson.DbInterface; import org.opendcs.odcsapi.sec.AuthorizationCheck; -import org.opendcs.odcsapi.util.ApiConstants; -import org.opendcs.odcsapi.util.ApiHttpUtil; @Path("/") -public class RoutingResources +public class RoutingResources extends OpenDcsResource { @Context private HttpServletRequest request; @Context private HttpHeaders httpHeaders; + private DatabaseIO dbIo; @GET @Path("routingrefs") @@ -56,69 +75,236 @@ public class RoutingResources @RolesAllowed({AuthorizationCheck.ODCS_API_GUEST}) public Response getRoutingRefs() throws DbException { - Logger.getLogger(ApiConstants.loggerName).fine("getRoutingRefs"); - try (DbInterface dbi = new DbInterface(); - ApiRoutingDAO dao = new ApiRoutingDAO(dbi)) + try { - return ApiHttpUtil.createResponse(dao.getRoutingRefs()); + dbIo = getLegacyDatabase(); + RoutingSpecList rsList = new RoutingSpecList(); + dbIo.readRoutingSpecList(rsList); + return Response.status(HttpServletResponse.SC_OK) + .entity(map(rsList)).build(); + } + catch(DatabaseException e) + { + throw new DbException("Unable to retrieve routing reference list", e); + } + finally + { + dbIo.close(); } } + static List map(RoutingSpecList rsList) + { + // This map does not map the destination value to the ApiRoutingRef object. + List refs = new ArrayList<>(); + rsList.getList().forEach(rs -> { + ApiRoutingRef ref = new ApiRoutingRef(); + if (rs.getId() != null) + { + ref.setRoutingId(rs.getId().getValue()); + } + else + { + ref.setRoutingId(DbKey.NullKey.getValue()); + } + ref.setName(rs.getName()); + if (rs.dataSource != null) + { + ref.setDataSourceName(rs.dataSource.getName()); + } + ref.setLastModified(rs.lastModifyTime); + refs.add(ref); + }); + return refs; + } + @GET @Path("routing") @Produces(MediaType.APPLICATION_JSON) @RolesAllowed({AuthorizationCheck.ODCS_API_GUEST}) public Response getRouting(@QueryParam("routingid") Long routingId) - throws WebAppException, DbException, SQLException + throws WebAppException, DbException { - + if (routingId == null) - throw new WebAppException(ErrorCodes.MISSING_ID, - "Missing required routingid parameter."); - - Logger.getLogger(ApiConstants.loggerName).fine("getRouting id=" + routingId); - try (DbInterface dbi = new DbInterface(); - ApiRoutingDAO dao = new ApiRoutingDAO(dbi)) { - return ApiHttpUtil.createResponse(dao.getRouting(routingId)); + throw new WebAppException(HttpServletResponse.SC_BAD_REQUEST, + "Missing required routingid parameter."); + } + + try + { + dbIo = getLegacyDatabase(); + RoutingSpec spec = new RoutingSpec(); + spec.setId(DbKey.createDbKey(routingId)); + dbIo.readRoutingSpec(spec); + return Response.status(HttpServletResponse.SC_OK) + .entity(map(spec)).build(); + } + catch(DatabaseException e) + { + if (e.getMessage().contains("No RoutingSpec found with id")) + { + return Response.status(HttpServletResponse.SC_NOT_FOUND).build(); + } + throw new DbException("Unable to retrieve routing spec by ID", e); + } + finally + { + dbIo.close(); } } + static ApiRouting map(RoutingSpec spec) { + // This map does not map the goesSelfTimed value to the ApiRouting object. + ApiRouting routing = new ApiRouting(); + if (spec.getId() != null) + { + routing.setRoutingId(spec.getId().getValue()); + } + else + { + routing.setRoutingId(DbKey.NullKey.getValue()); + } + routing.setName(spec.getName()); + routing.setLastModified(spec.lastModifyTime); + if (spec.outputTimeZoneAbbr != null) + { + routing.setOutputTZ(spec.outputTimeZoneAbbr); + } + routing.setNetlistNames(new ArrayList<>(spec.networkListNames)); + routing.setOutputFormat(spec.outputFormat); + routing.setEnableEquations(spec.enableEquations); + if (spec.dataSource != null) + { + routing.setDataSourceId(spec.dataSource.getId().getValue()); + routing.setDataSourceName(spec.dataSource.getName()); + } + routing.setDestinationArg(spec.consumerArg); + routing.setDestinationType(spec.consumerType); + routing.setPresGroupName(spec.presentationGroupName); + routing.setSince(spec.sinceTime); + routing.setUntil(spec.untilTime); + routing.setProperties(spec.getProperties()); + return routing; + } + @POST @Path("routing") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @RolesAllowed({AuthorizationCheck.ODCS_API_ADMIN, AuthorizationCheck.ODCS_API_USER}) public Response postRouting(ApiRouting routing) - throws WebAppException, DbException, SQLException + throws DbException { - Logger.getLogger(ApiConstants.loggerName).fine("post routing received routing " + routing.getName() - + " with ID=" + routing.getRoutingId()); - - try (DbInterface dbi = new DbInterface(); - ApiRoutingDAO dao = new ApiRoutingDAO(dbi)) + try + { + dbIo = getLegacyDatabase(); + RoutingSpec spec = map(routing); + dbIo.writeRoutingSpec(spec); + return Response.status(HttpServletResponse.SC_OK).entity(map(spec)).build(); + } + catch(DatabaseException e) + { + throw new DbException("Unable to store routing spec", e); + } + finally { - dao.writeRouting(routing); - return ApiHttpUtil.createResponse(routing); + dbIo.close(); } } + static RoutingSpec map(ApiRouting routing) throws DbException + { + try + { + RoutingSpec spec = new RoutingSpec(); + if (routing.getRoutingId() != null) + { + spec.setId(DbKey.createDbKey(routing.getRoutingId())); + } + else + { + spec.setId(DbKey.NullKey); + } + spec.setName(routing.getName()); + spec.usePerformanceMeasurements = false; + spec.lastModifyTime = routing.getLastModified(); + if (routing.getOutputTZ() != null) + { + spec.outputTimeZoneAbbr = routing.getOutputTZ(); + spec.outputTimeZone = TimeZone.getTimeZone(ZoneId.of(routing.getOutputTZ())); + } + routing.getNetlistNames().forEach(spec::addNetworkListName); + spec.outputFormat = routing.getOutputFormat(); + spec.enableEquations = routing.isEnableEquations(); + spec.presentationGroupName = routing.getPresGroupName(); + spec.isProduction = routing.isProduction(); + spec.consumerArg = routing.getDestinationArg(); + spec.consumerType = routing.getDestinationType(); + if (routing.getSince() != null) + { + spec.sinceTime = routing.getSince(); + } + if (routing.getUntil() != null) + { + spec.untilTime = routing.getUntil(); + } + spec.setProperties(routing.getProperties()); + if (routing.getDataSourceId() != null) + { + DataSource dataSource = new DataSource(); + if (routing.getDataSourceId() != null) + { + dataSource.setId(DbKey.createDbKey(routing.getDataSourceId())); + } + else + { + dataSource.setId(DbKey.NullKey); + } + dataSource.setName(routing.getDataSourceName()); + spec.dataSource = dataSource; + } + spec.networkListNames = new Vector<>(routing.getNetlistNames()); + return spec; + } + catch(DatabaseException e) + { + throw new DbException("Unable to map routing spec", e); + } + + } + @DELETE @Path("routing") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) + @RolesAllowed({AuthorizationCheck.ODCS_API_ADMIN, AuthorizationCheck.ODCS_API_USER}) public Response deleteRouting(@QueryParam("routingid") Long routingId) - throws WebAppException, DbException, SQLException + throws DbException, WebAppException { - Logger.getLogger(ApiConstants.loggerName) - .fine("DELETE routing received routingId=" + routingId); - - // Use username and password to attempt to connect to the database - try (DbInterface dbi = new DbInterface(); - ApiRoutingDAO dao = new ApiRoutingDAO(dbi)) + if (routingId == null) + { + throw new WebAppException(HttpServletResponse.SC_BAD_REQUEST, + "Missing required routingid parameter."); + } + + try + { + dbIo = getLegacyDatabase(); + RoutingSpec spec = new RoutingSpec(); + spec.setId(DbKey.createDbKey(routingId)); + dbIo.deleteRoutingSpec(spec); + return Response.status(HttpServletResponse.SC_OK) + .entity("RoutingSpec with ID " + routingId + " deleted").build(); + } + catch(DatabaseException e) + { + throw new DbException("Unable to delete routing spec", e); + } + finally { - dao.deleteRouting(routingId); - return ApiHttpUtil.createResponse("RoutingSpec with ID " + routingId + " deleted"); + dbIo.close(); } } @@ -127,32 +313,68 @@ public Response deleteRouting(@QueryParam("routingid") Long routingId) @Produces(MediaType.APPLICATION_JSON) @RolesAllowed({AuthorizationCheck.ODCS_API_GUEST}) public Response getScheduleRefs() - throws DbException + throws DbException { - Logger.getLogger(ApiConstants.loggerName).fine("getScheduleRefs"); - try (DbInterface dbi = new DbInterface(); - ApiRoutingDAO dao = new ApiRoutingDAO(dbi)) + + try (ScheduleEntryDAI dai = getLegacyDatabase().makeScheduleEntryDAO()) { - return ApiHttpUtil.createResponse(dao.getScheduleRefs()); + List entries = dai.listScheduleEntries(null); + return Response.status(HttpServletResponse.SC_OK) + .entity(map(entries)).build(); } + catch(DbIoException e) + { + throw new DbException("Unable to retrieve schedule entry ref list", e); + } + } + + static List map(List entries) + { + List refs = new ArrayList<>(); + entries.forEach(entry -> { + ApiScheduleEntryRef ref = new ApiScheduleEntryRef(); + if (entry.getId() != null) + { + ref.setSchedEntryId(entry.getId().getValue()); + } + else + { + ref.setSchedEntryId(DbKey.NullKey.getValue()); + } + ref.setEnabled(entry.isEnabled()); + ref.setAppName(entry.getLoadingAppName()); + ref.setName(entry.getName()); + ref.setLastModified(entry.getLastModified()); + ref.setRoutingSpecName(entry.getRoutingSpecName()); + refs.add(ref); + }); + return refs; } @GET @Path("schedule") @Produces(MediaType.APPLICATION_JSON) @RolesAllowed({AuthorizationCheck.ODCS_API_GUEST}) - public Response getSchedule(@QueryParam("scheduleid") Long scheduleId) - throws WebAppException, DbException, SQLException + public Response getSchedule(@QueryParam("scheduleid") Long scheduleId) + throws WebAppException, DbException { if (scheduleId == null) - throw new WebAppException(ErrorCodes.MISSING_ID, - "Missing required scheduleid parameter."); - - Logger.getLogger(ApiConstants.loggerName).fine("getSchedule id=" + scheduleId); - try (DbInterface dbi = new DbInterface(); - ApiRoutingDAO dao = new ApiRoutingDAO(dbi)) + throw new WebAppException(HttpServletResponse.SC_BAD_REQUEST, + "Missing required scheduleid parameter."); + try (ScheduleEntryDAI dai = getLegacyDatabase().makeScheduleEntryDAO()) + { + ScheduleEntry entry = dai.readScheduleEntry(DbKey.createDbKey(scheduleId)); + if (entry == null) + { + return Response.status(HttpServletResponse.SC_NOT_FOUND).build(); + } + return Response.status(HttpServletResponse.SC_OK) + .entity(map(entry)) + .build(); + } + catch(DbIoException e) { - return ApiHttpUtil.createResponse(dao.getSchedule(scheduleId)); + throw new DbException("Unable to retrieve schedule entry by ID", e); } } @@ -162,36 +384,109 @@ public Response getSchedule(@QueryParam("scheduleid") Long scheduleId) @Produces(MediaType.APPLICATION_JSON) @RolesAllowed({AuthorizationCheck.ODCS_API_ADMIN, AuthorizationCheck.ODCS_API_USER}) public Response postSchedule(ApiScheduleEntry schedule) - throws WebAppException, DbException, SQLException + throws DbException { - Logger.getLogger(ApiConstants.loggerName).fine("post schedule received sched " + schedule.getName() - + " with ID=" + schedule.getSchedEntryId()); - - try (DbInterface dbi = new DbInterface(); - ApiRoutingDAO dao = new ApiRoutingDAO(dbi)) + try (ScheduleEntryDAI dai = getLegacyDatabase().makeScheduleEntryDAO()) { - dao.writeSchedule(schedule); - return ApiHttpUtil.createResponse(schedule); + ScheduleEntry entry = map(schedule); + dai.writeScheduleEntry(entry); + return Response.status(HttpServletResponse.SC_OK) + .entity(map(entry)) + .build(); + } + catch (DbIoException e) + { + throw new DbException("Unable to store schedule entry", e); } } + static ScheduleEntry map(ApiScheduleEntry schedule) throws DbException + { + try + { + ScheduleEntry entry = new ScheduleEntry(schedule.getName()); + if (schedule.getSchedEntryId() != null) + { + entry.setId(DbKey.createDbKey(schedule.getSchedEntryId())); + } + else + { + entry.setId(DbKey.NullKey); + } + entry.setStartTime(schedule.getStartTime()); + entry.setTimezone(schedule.getTimeZone()); + if (schedule.getAppId() != null) + { + entry.setLoadingAppId(DbKey.createDbKey(schedule.getAppId())); + entry.setLoadingAppName(schedule.getAppName()); + } + if (schedule.getRoutingSpecId() != null) + { + entry.setRoutingSpecId(DbKey.createDbKey(schedule.getRoutingSpecId())); + entry.setRoutingSpecName(schedule.getRoutingSpecName()); + } + entry.setRunInterval(schedule.getRunInterval()); + entry.setLastModified(schedule.getLastModified()); + return entry; + } + catch (DatabaseException e) + { + throw new DbException("Unable to map schedule entry", e); + } + } + + static ApiScheduleEntry map(ScheduleEntry entry) + { + ApiScheduleEntry schedule = new ApiScheduleEntry(); + if (entry.getId() != null) + { + schedule.setSchedEntryId(entry.getId().getValue()); + } + else + { + schedule.setSchedEntryId(DbKey.NullKey.getValue()); + } + schedule.setName(entry.getName()); + schedule.setStartTime(entry.getStartTime()); + schedule.setTimeZone(entry.getTimezone()); + schedule.setEnabled(entry.isEnabled()); + if (entry.getLoadingAppId() != null) + { + schedule.setAppId(entry.getLoadingAppId().getValue()); + schedule.setAppName(entry.getLoadingAppName()); + } + if (entry.getRoutingSpecId() != null) + { + schedule.setRoutingSpecId(entry.getRoutingSpecId().getValue()); + schedule.setRoutingSpecName(entry.getRoutingSpecName()); + } + schedule.setRunInterval(entry.getRunInterval()); + schedule.setLastModified(entry.getLastModified()); + return schedule; + } + @DELETE @Path("schedule") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @RolesAllowed({AuthorizationCheck.ODCS_API_ADMIN, AuthorizationCheck.ODCS_API_USER}) public Response deleteSchedule(@QueryParam("scheduleid") Long scheduleId) - throws WebAppException, DbException + throws DbException, WebAppException { - Logger.getLogger(ApiConstants.loggerName) - .fine("DELETE schedule received scheduleId=" + scheduleId); - - // Use username and password to attempt to connect to the database - try (DbInterface dbi = new DbInterface(); - ApiRoutingDAO dao = new ApiRoutingDAO(dbi)) + if (scheduleId == null) + { + throw new WebAppException(HttpServletResponse.SC_BAD_REQUEST, "missing required scheduleid argument."); + } + try (ScheduleEntryDAI dai = getLegacyDatabase().makeScheduleEntryDAO()) + { + ScheduleEntry entry = new ScheduleEntry(DbKey.createDbKey(scheduleId)); + dai.deleteScheduleEntry(entry); + return Response.status(HttpServletResponse.SC_OK) + .entity("Schedule entry with ID " + scheduleId + " deleted").build(); + } + catch (DbIoException e) { - dao.deleteSchedule(scheduleId); - return ApiHttpUtil.createResponse("schedulec with ID " + scheduleId + " deleted"); + throw new DbException(String.format("Unable to delete schedule entry by ID: %s", scheduleId), e); } } @@ -201,14 +496,66 @@ public Response deleteSchedule(@QueryParam("scheduleid") Long scheduleId) @Produces(MediaType.APPLICATION_JSON) @RolesAllowed({AuthorizationCheck.ODCS_API_GUEST}) public Response getRoutingStats() - throws WebAppException, DbException + throws DbException + { + try (ScheduleEntryDAI dai = getLegacyDatabase().makeScheduleEntryDAO()) + { + return Response.status(HttpServletResponse.SC_OK) + .entity(dai.listScheduleEntries(null) + .stream() + .map(RoutingResources::statusMap) + .collect(Collectors.toList())) + .build(); + } + catch (DbIoException e) + { + throw new DbException("Unable to retrieve routing status", e); + } + } + + static ApiRoutingStatus statusMap(ScheduleEntry entry) + { + ApiRoutingStatus status = new ApiRoutingStatus(); + if (entry.getId() != null) + { + status.setScheduleEntryId(entry.getId().getValue()); + } + else + { + status.setScheduleEntryId(DbKey.NullKey.getValue()); + } + status.setAppName(entry.getLoadingAppName()); + if (entry.getLoadingAppId() != null) + { + status.setAppId(entry.getLoadingAppId().getValue()); + } + status.setName(entry.getName()); + status.setEnabled(entry.isEnabled()); + if (entry.getRoutingSpecId() != null) + { + status.setRoutingSpecId(entry.getRoutingSpecId().getValue()); + } + status.setRunInterval(entry.getRunInterval()); + status.setLastActivity(entry.getLastModified()); + return status; + } + + static ArrayList map(ArrayList entries) { - Logger.getLogger(ApiConstants.loggerName).fine("getRoutingStats"); - try (DbInterface dbi = new DbInterface(); - ApiRoutingDAO dao = new ApiRoutingDAO(dbi)) + ArrayList refs = new ArrayList<>(); + for (ScheduleEntry entry : entries) { - return ApiHttpUtil.createResponse(dao.getRsStatus()); + ApiScheduleEntryRef ref = new ApiScheduleEntryRef(); + ref.setSchedEntryId(entry.getId().getValue()); + ref.setEnabled(entry.isEnabled()); + ref.setAppName(entry.getLoadingAppName()); + ref.setName(entry.getName()); + ref.setLastModified(entry.getLastModified()); + ref.setRoutingSpecName(entry.getRoutingSpecName()); + refs.add(ref); } + + return refs; } @GET @@ -216,17 +563,50 @@ public Response getRoutingStats() @Produces(MediaType.APPLICATION_JSON) @RolesAllowed({AuthorizationCheck.ODCS_API_GUEST}) public Response getRoutingExecStatus(@QueryParam("scheduleentryid") Long scheduleEntryId) - throws WebAppException, DbException + throws WebAppException, DbException { if (scheduleEntryId == null) - throw new WebAppException(ErrorCodes.MISSING_ID, "missing required scheduleentryid argument."); - - Logger.getLogger(ApiConstants.loggerName).fine("getRoutingExecStatus"); - try (DbInterface dbi = new DbInterface(); - ApiRoutingDAO dao = new ApiRoutingDAO(dbi)) { - return ApiHttpUtil.createResponse(dao.getRoutingExecStatus(scheduleEntryId)); + throw new WebAppException(HttpServletResponse.SC_BAD_REQUEST, "missing required scheduleentryid argument."); + } + + try (ScheduleEntryDAI dai = getLegacyDatabase().makeScheduleEntryDAO()) + { + ScheduleEntry entry = new ScheduleEntry(DbKey.createDbKey(scheduleEntryId)); + return Response.status(HttpServletResponse.SC_OK) + .entity(statusMap(dai.readScheduleStatus(entry))).build(); + } + catch (DbIoException e) + { + throw new DbException("Unable to retrieve routing exec status", e); + } + } + + static ArrayList statusMap(ArrayList statuses) + { + ArrayList execStatuses = new ArrayList<>(); + for (ScheduleEntryStatus status : statuses) + { + ApiRoutingExecStatus execStatus = new ApiRoutingExecStatus(); + if (status.getScheduleEntryId() != null) + { + execStatus.setScheduleEntryId(status.getScheduleEntryId().getValue()); + } + else + { + execStatus.setScheduleEntryId(DbKey.NullKey.getValue()); + } + execStatus.setHostname(status.getHostname()); + execStatus.setNumErrors(status.getNumDecodesErrors()); + execStatus.setRunStatus(status.getRunStatus()); + execStatus.setRunStop(status.getRunStop()); + execStatus.setRunStart(status.getRunStart()); + execStatus.setNumPlatforms(status.getNumPlatforms()); + execStatus.setNumMessages(status.getNumMessages()); + execStatus.setLastActivity(status.getLastModified()); + execStatuses.add(execStatus); } + return execStatuses; } @GET @@ -234,15 +614,38 @@ public Response getRoutingExecStatus(@QueryParam("scheduleentryid") Long schedul @Produces(MediaType.APPLICATION_JSON) @RolesAllowed({AuthorizationCheck.ODCS_API_ADMIN, AuthorizationCheck.ODCS_API_USER}) public Response getDacqEvents(@QueryParam("appid") Long appId, @QueryParam("routingexecid") Long routingExecId, - @QueryParam("platformid") Long platformId, @QueryParam("backlog") String backlog) - throws DbException + @QueryParam("platformid") Long platformId, @QueryParam("backlog") String backlog) + throws DbException { - Logger.getLogger(ApiConstants.loggerName).fine("getDacqEvents"); - try (DbInterface dbi = new DbInterface(); - ApiRoutingDAO dao = new ApiRoutingDAO(dbi)) + try (DacqEventDAI dai = getLegacyTimeseriesDB().makeDacqEventDAO()) { HttpSession session = request.getSession(true); - return ApiHttpUtil.createResponse(dao.getDacqEvents(appId, routingExecId, platformId, backlog, session)); + ArrayList events = new ArrayList<>(); + dai.readEvents(events, appId != null ? DbKey.createDbKey(appId) : DbKey.NullKey, + routingExecId != null ? DbKey.createDbKey(routingExecId) : DbKey.NullKey, + platformId != null ? DbKey.createDbKey(platformId) : DbKey.NullKey, + backlog, session); + return Response.status(HttpServletResponse.SC_OK) + .entity(events.stream().map(RoutingResources::map).collect(Collectors.toList())).build(); + } + catch (DbIoException e) + { + throw new DbException("Unable to retrieve dacq events", e); } } + + static ApiDacqEvent map(DacqEvent event) + { + ApiDacqEvent apiEvent = new ApiDacqEvent(); + apiEvent.setEventId(event.getDacqEventId().getValue()); + apiEvent.setAppId(event.getAppId().getValue()); + apiEvent.setPlatformId(event.getPlatformId().getValue()); + apiEvent.setRoutingExecId(event.getScheduleEntryStatusId().getValue()); + apiEvent.setPriority(Logger.priorityName[event.getEventPriority()]); + apiEvent.setEventTime(event.getEventTime()); + apiEvent.setEventText(event.getEventText()); + apiEvent.setSubsystem(event.getSubsystem()); + apiEvent.setMsgRecvTime(event.getMsgRecvTime()); + return apiEvent; + } } diff --git a/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/RoutingResourcesTest.java b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/RoutingResourcesTest.java new file mode 100644 index 00000000..e5213b56 --- /dev/null +++ b/opendcs-rest-api/src/test/java/org/opendcs/odcsapi/res/RoutingResourcesTest.java @@ -0,0 +1,322 @@ +package org.opendcs.odcsapi.res; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; +import java.util.Vector; + +import decodes.db.DataSource; +import decodes.db.RoutingSpec; +import decodes.db.RoutingSpecList; +import decodes.db.ScheduleEntry; +import decodes.db.ScheduleEntryStatus; +import decodes.polling.DacqEvent; +import decodes.sql.DbKey; +import ilex.util.Logger; +import org.junit.jupiter.api.Test; +import org.opendcs.odcsapi.beans.ApiDacqEvent; +import org.opendcs.odcsapi.beans.ApiRouting; +import org.opendcs.odcsapi.beans.ApiRoutingExecStatus; +import org.opendcs.odcsapi.beans.ApiRoutingRef; +import org.opendcs.odcsapi.beans.ApiRoutingStatus; +import org.opendcs.odcsapi.beans.ApiScheduleEntry; +import org.opendcs.odcsapi.beans.ApiScheduleEntryRef; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.fail; +import static org.opendcs.odcsapi.res.RoutingResources.map; +import static org.opendcs.odcsapi.res.RoutingResources.statusMap; + +final class RoutingResourcesTest +{ + @Test + void testRoutingRefListMap() throws Exception + { + RoutingSpecList routingSpecList = new RoutingSpecList(); + RoutingSpec routingSpec = buildRoutingSpec(); + routingSpecList.add(routingSpec); + List apiRoutingRefs = map(routingSpecList); + ApiRoutingRef apiRoutingRef = apiRoutingRefs.get(0); + assertNotNull(apiRoutingRef); + assertEquals(apiRoutingRef.getRoutingId(), routingSpec.getId().getValue()); + assertEquals(apiRoutingRef.getName(), routingSpec.getName()); + assertEquals(apiRoutingRef.getDataSourceName(), routingSpec.dataSource.getName()); + assertEquals(apiRoutingRef.getLastModified(), routingSpec.lastModifyTime); + } + + @Test + void testApiRoutingMap() throws Exception + { + RoutingSpec routingSpec = buildRoutingSpec(); + + ApiRouting apiRouting = map(routingSpec); + + assertNotNull(apiRouting); + assertEquals(apiRouting.getRoutingId(), routingSpec.getId().getValue()); + assertEquals(apiRouting.getName(), routingSpec.getName()); + assertEquals(apiRouting.getOutputTZ(), routingSpec.outputTimeZoneAbbr); + assertEquals(apiRouting.getLastModified(), routingSpec.lastModifyTime); + assertEquals(apiRouting.isEnableEquations(), routingSpec.enableEquations); + assertEquals(new Vector<>(apiRouting.getNetlistNames()), routingSpec.networkListNames); + assertEquals(apiRouting.getDataSourceName(), routingSpec.dataSource.getName()); + assertEquals(apiRouting.getDestinationType(), routingSpec.consumerType); + assertEquals(apiRouting.getDestinationArg(), routingSpec.consumerArg); + assertEquals(apiRouting.getDataSourceId(), routingSpec.dataSource.getId().getValue()); + assertEquals(apiRouting.getPresGroupName(), routingSpec.presentationGroupName); + assertEquals(apiRouting.getSince(), routingSpec.sinceTime); + assertEquals(apiRouting.getUntil(), routingSpec.untilTime); + assertEquals(apiRouting.getDataSourceId(), routingSpec.dataSource.getId().getValue()); + assertEquals(apiRouting.getProperties(), routingSpec.getProperties()); + } + + @Test + void testRoutingSpecMap() throws Exception + { + ApiRouting apiRouting = new ApiRouting(); + apiRouting.setRoutingId(1234L); + apiRouting.setName("TestRoutingSpec"); + RoutingSpec routingSpec = map(apiRouting); + assertNotNull(routingSpec); + assertEquals(routingSpec.getId().getValue(), apiRouting.getRoutingId()); + assertEquals(routingSpec.getName(), apiRouting.getName()); + if (routingSpec.outputTimeZone != null) + { + assertEquals(routingSpec.outputTimeZone.getID(), apiRouting.getOutputTZ()); + } + else if (apiRouting.getOutputTZ() != null) + { + fail("routingSpec.outputTimeZone is null, but apiRouting.getOutputTZ() is not null"); + } + assertEquals(routingSpec.lastModifyTime, apiRouting.getLastModified()); + assertEquals(routingSpec.enableEquations, apiRouting.isEnableEquations()); + assertEquals(routingSpec.networkListNames, new Vector<>(apiRouting.getNetlistNames())); + } + + @Test + void testScheduleEntryRefMap() + { + List scheduleEntries = new ArrayList<>(); + ScheduleEntry scheduleEntry = new ScheduleEntry(DbKey.createDbKey(1234L)); + scheduleEntry.setEnabled(true); + scheduleEntry.setName("TestScheduleEntry"); + scheduleEntry.setRoutingSpecId(DbKey.createDbKey(5678L)); + scheduleEntry.setLastModified(Date.from(Instant.parse("2021-02-01T00:00:00Z"))); + scheduleEntry.setLoadingAppName("TestAppName"); + scheduleEntry.setRoutingSpecName("TestRoutingSpec"); + scheduleEntry.setTimezone("UTC"); + scheduleEntry.setStartTime(Date.from(Instant.parse("2021-01-01T00:00:00Z"))); + scheduleEntries.add(scheduleEntry); + List apiScheduleEntryRefs = map(scheduleEntries); + assertNotNull(apiScheduleEntryRefs); + ApiScheduleEntryRef apiScheduleEntryRef = apiScheduleEntryRefs.get(0); + assertNotNull(apiScheduleEntryRef); + assertEquals(apiScheduleEntryRef.getSchedEntryId(), scheduleEntry.getKey().getValue()); + assertEquals(apiScheduleEntryRef.getName(), scheduleEntry.getName()); + assertEquals(apiScheduleEntryRef.getAppName(), scheduleEntry.getLoadingAppName()); + assertEquals(apiScheduleEntryRef.getRoutingSpecName(), scheduleEntry.getRoutingSpecName()); + assertEquals(apiScheduleEntryRef.getLastModified(), scheduleEntry.getLastModified()); + } + + @Test + void testScheduleEntryMap() throws Exception + { + ApiScheduleEntry apiScheduleEntry = new ApiScheduleEntry(); + apiScheduleEntry.setSchedEntryId(1234L); + apiScheduleEntry.setName("TestScheduleEntry"); + apiScheduleEntry.setAppName("TestAppName"); + apiScheduleEntry.setRoutingSpecName("TestRoutingSpec"); + apiScheduleEntry.setLastModified(Date.from(Instant.parse("2021-02-01T00:00:00Z"))); + apiScheduleEntry.setAppId(5678L); + apiScheduleEntry.setRoutingSpecId(9012L); + apiScheduleEntry.setStartTime(Date.from(Instant.parse("2021-01-01T00:00:00Z"))); + apiScheduleEntry.setEnabled(true); + apiScheduleEntry.setTimeZone("UTC"); + apiScheduleEntry.setRunInterval("1h"); + ScheduleEntry scheduleEntry = map(apiScheduleEntry); + assertNotNull(scheduleEntry); + assertEquals(scheduleEntry.getKey().getValue(), apiScheduleEntry.getSchedEntryId()); + assertEquals(scheduleEntry.getName(), apiScheduleEntry.getName()); + assertEquals(scheduleEntry.getLoadingAppName(), apiScheduleEntry.getAppName()); + assertEquals(scheduleEntry.getRoutingSpecName(), apiScheduleEntry.getRoutingSpecName()); + assertEquals(scheduleEntry.getLastModified(), apiScheduleEntry.getLastModified()); + assertEquals(scheduleEntry.getLoadingAppId().getValue(), apiScheduleEntry.getAppId()); + assertEquals(scheduleEntry.getRoutingSpecId().getValue(), apiScheduleEntry.getRoutingSpecId()); + assertEquals(scheduleEntry.getStartTime(), apiScheduleEntry.getStartTime()); + assertEquals(scheduleEntry.isEnabled(), apiScheduleEntry.isEnabled()); + assertEquals(scheduleEntry.getTimezone(), apiScheduleEntry.getTimeZone()); + assertEquals(scheduleEntry.getRunInterval(), apiScheduleEntry.getRunInterval()); + } + + @Test + void testApiScheduleEntryListMap() + { + ArrayList scheduleEntries = new ArrayList<>(); + ScheduleEntry scheduleEntry = new ScheduleEntry(DbKey.createDbKey(1234L)); + scheduleEntry.setName("TestScheduleEntry"); + scheduleEntry.setLoadingAppName("TestAppName"); + scheduleEntry.setRoutingSpecName("TestRoutingSpec"); + scheduleEntry.setLastModified(Date.from(Instant.parse("2021-02-01T00:00:00Z"))); + scheduleEntry.setLoadingAppId(DbKey.createDbKey(5678L)); + scheduleEntry.setRoutingSpecId(DbKey.createDbKey(9012L)); + scheduleEntry.setStartTime(Date.from(Instant.parse("2021-01-01T00:00:00Z"))); + scheduleEntry.setEnabled(true); + scheduleEntry.setTimezone("UTC"); + scheduleEntry.setRunInterval("1h"); + scheduleEntries.add(scheduleEntry); + + ArrayList results = map(scheduleEntries); + + assertNotNull(results); + assertEquals(1, results.size()); + ApiScheduleEntryRef result = results.get(0); + assertNotNull(result); + assertEquals(scheduleEntry.getKey().getValue(), result.getSchedEntryId()); + assertEquals(scheduleEntry.getName(), result.getName()); + assertEquals(scheduleEntry.getLoadingAppName(), result.getAppName()); + assertEquals(scheduleEntry.getRoutingSpecName(), result.getRoutingSpecName()); + assertEquals(scheduleEntry.getLastModified(), result.getLastModified()); + } + + @Test + void testRoutingStatusMap() + { + ArrayList scheduleEntries = new ArrayList<>(); + ScheduleEntryStatus scheduleEntry = new ScheduleEntryStatus(DbKey.createDbKey(1234L)); + scheduleEntry.setScheduleEntryName("TestScheduleEntry"); + scheduleEntry.setLastModified(Date.from(Instant.parse("2021-02-01T00:00:00Z"))); + scheduleEntry.setHostname("TestHost"); + scheduleEntry.setRunStatus("TestStatus"); + scheduleEntry.setNumDecodesErrors(10); + scheduleEntry.setNumMessages(20); + scheduleEntry.setNumPlatforms(30); + scheduleEntry.setRunStop(Date.from(Instant.parse("2021-03-01T00:00:00Z"))); + scheduleEntry.setRunStart(Date.from(Instant.parse("2021-02-01T00:00:00Z"))); + scheduleEntry.setLastModified(Date.from(Instant.parse("2021-04-01T00:00:00Z"))); + scheduleEntries.add(scheduleEntry); + + ArrayList results = statusMap(scheduleEntries); + assertNotNull(results); + assertEquals(1, results.size()); + ApiRoutingExecStatus result = results.get(0); + assertNotNull(result); + assertEquals(scheduleEntry.getScheduleEntryId().getValue(), result.getScheduleEntryId()); + assertEquals(scheduleEntry.getHostname(), result.getHostname()); + assertEquals(scheduleEntry.getRunStatus(), result.getRunStatus()); + assertEquals(scheduleEntry.getNumDecodesErrors(), result.getNumErrors()); + assertEquals(scheduleEntry.getNumMessages(), result.getNumMessages()); + assertEquals(scheduleEntry.getNumPlatforms(), result.getNumPlatforms()); + assertEquals(scheduleEntry.getRunStop(), result.getRunStop()); + assertEquals(scheduleEntry.getRunStart(), result.getRunStart()); + assertEquals(scheduleEntry.getLastModified(), result.getLastActivity()); + } + + @Test + void testApiScheduleEntryMap() + { + ScheduleEntry scheduleEntry = new ScheduleEntry(DbKey.createDbKey(1234L)); + scheduleEntry.setName("TestScheduleEntry"); + scheduleEntry.setLoadingAppName("TestAppName"); + scheduleEntry.setRoutingSpecName("TestRoutingSpec"); + scheduleEntry.setLastModified(Date.from(Instant.parse("2021-02-01T00:00:00Z"))); + scheduleEntry.setLoadingAppId(DbKey.createDbKey(5678L)); + scheduleEntry.setRoutingSpecId(DbKey.createDbKey(9012L)); + scheduleEntry.setStartTime(Date.from(Instant.parse("2021-01-01T00:00:00Z"))); + scheduleEntry.setEnabled(true); + scheduleEntry.setTimezone("UTC"); + scheduleEntry.setRunInterval("1h"); + + ApiScheduleEntry apiScheduleEntry = map(scheduleEntry); + assertNotNull(apiScheduleEntry); + assertEquals(apiScheduleEntry.getSchedEntryId(), scheduleEntry.getKey().getValue()); + assertEquals(apiScheduleEntry.getName(), scheduleEntry.getName()); + assertEquals(apiScheduleEntry.getAppName(), scheduleEntry.getLoadingAppName()); + assertEquals(apiScheduleEntry.getRoutingSpecName(), scheduleEntry.getRoutingSpecName()); + assertEquals(apiScheduleEntry.getLastModified(), scheduleEntry.getLastModified()); + assertEquals(apiScheduleEntry.getAppId(), scheduleEntry.getLoadingAppId().getValue()); + assertEquals(apiScheduleEntry.getRoutingSpecId(), scheduleEntry.getRoutingSpecId().getValue()); + assertEquals(apiScheduleEntry.getStartTime(), scheduleEntry.getStartTime()); + assertEquals(apiScheduleEntry.isEnabled(), scheduleEntry.isEnabled()); + assertEquals(apiScheduleEntry.getTimeZone(), scheduleEntry.getTimezone()); + assertEquals(apiScheduleEntry.getRunInterval(), scheduleEntry.getRunInterval()); + } + + @Test + void testDacqEventMap() + { + DacqEvent dacqEvent = new DacqEvent(); + dacqEvent.setAppId(DbKey.createDbKey(1234L)); + dacqEvent.setDacqEventId(DbKey.createDbKey(5678L)); + dacqEvent.setEventText("TestEvent"); + dacqEvent.setEventTime(Date.from(Instant.parse("2021-02-01T00:00:00Z"))); + dacqEvent.setEventPriority(Logger.E_DEBUG1); + dacqEvent.setMsgRecvTime(Date.from(Instant.parse("2021-02-01T12:00:00Z"))); + dacqEvent.setSubsystem("TestSubsystem"); + dacqEvent.setScheduleEntryStatusId(DbKey.createDbKey(9012L)); + dacqEvent.setPlatformId(DbKey.createDbKey(3456L)); + + ApiDacqEvent apiDacqEvent = map(dacqEvent); + + assertNotNull(apiDacqEvent); + assertEquals(apiDacqEvent.getAppId(), dacqEvent.getAppId().getValue()); + assertEquals(apiDacqEvent.getEventId(), dacqEvent.getDacqEventId().getValue()); + assertEquals(apiDacqEvent.getEventText(), dacqEvent.getEventText()); + assertEquals(apiDacqEvent.getEventTime(), dacqEvent.getEventTime()); + assertEquals(apiDacqEvent.getPriority(), Logger.priorityName[dacqEvent.getEventPriority()]); + assertEquals(apiDacqEvent.getMsgRecvTime(), dacqEvent.getMsgRecvTime()); + assertEquals(apiDacqEvent.getSubsystem(), dacqEvent.getSubsystem()); + assertEquals(apiDacqEvent.getRoutingExecId(), dacqEvent.getScheduleEntryStatusId().getValue()); + assertEquals(apiDacqEvent.getPlatformId(), dacqEvent.getPlatformId().getValue()); + } + + @Test + void testStatusMap() + { + ScheduleEntry scheduleEntry = new ScheduleEntry(DbKey.createDbKey(1234L)); + scheduleEntry.setName("TestScheduleEntry"); + scheduleEntry.setLoadingAppName("TestAppName"); + scheduleEntry.setRoutingSpecName("TestRoutingSpec"); + scheduleEntry.setLastModified(Date.from(Instant.parse("2021-02-01T00:00:00Z"))); + scheduleEntry.setLoadingAppId(DbKey.createDbKey(5678L)); + scheduleEntry.setRoutingSpecId(DbKey.createDbKey(9012L)); + scheduleEntry.setStartTime(Date.from(Instant.parse("2021-01-01T00:00:00Z"))); + scheduleEntry.setEnabled(true); + scheduleEntry.setTimezone("UTC"); + scheduleEntry.setRunInterval("1h"); + + ApiRoutingStatus apiRoutingStatus = statusMap(scheduleEntry); + + assertNotNull(apiRoutingStatus); + assertEquals(apiRoutingStatus.getScheduleEntryId(), scheduleEntry.getKey().getValue()); + assertEquals(apiRoutingStatus.getName(), scheduleEntry.getName()); + assertEquals(apiRoutingStatus.getAppName(), scheduleEntry.getLoadingAppName()); + assertEquals(apiRoutingStatus.getLastActivity(), scheduleEntry.getLastModified()); + assertEquals(apiRoutingStatus.getAppId(), scheduleEntry.getLoadingAppId().getValue()); + assertEquals(apiRoutingStatus.getRoutingSpecId(), scheduleEntry.getRoutingSpecId().getValue()); + assertEquals(apiRoutingStatus.isEnabled(), scheduleEntry.isEnabled()); + assertEquals(apiRoutingStatus.getRunInterval(), scheduleEntry.getRunInterval()); + } + + private RoutingSpec buildRoutingSpec() throws Exception + { + RoutingSpec routingSpec = new RoutingSpec(); + routingSpec.setName("TestRoutingSpec"); + routingSpec.setId(DbKey.createDbKey(1234L)); + routingSpec.outputTimeZone = TimeZone.getTimeZone("UTC"); + routingSpec.lastModifyTime = Date.from(Instant.parse("2021-02-01T00:00:00Z")); + routingSpec.enableEquations = true; + DataSource dataSource = new DataSource(); + dataSource.setName("TestDataSource"); + routingSpec.dataSource = dataSource; + routingSpec.consumerType = "TestConsumerType"; + routingSpec.consumerArg = "TestConsumerArg"; + routingSpec.networkListNames = new Vector<>(Arrays.asList("TestNet", "TestNet2")); + routingSpec.presentationGroupName = "TestPresGroup"; + routingSpec.sinceTime = "2021-01-01T00:00:00Z"; + routingSpec.untilTime ="2021-02-01T00:00:00Z"; + return routingSpec; + } +}