5 changed files with 371 additions and 1 deletions
@ -0,0 +1,275 @@ |
|||||||
|
package org.leolo.rail; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.io.FileNotFoundException; |
||||||
|
import java.io.PrintWriter; |
||||||
|
import java.sql.Connection; |
||||||
|
import java.sql.PreparedStatement; |
||||||
|
import java.sql.SQLException; |
||||||
|
import java.sql.Types; |
||||||
|
import java.text.ParseException; |
||||||
|
import java.text.SimpleDateFormat; |
||||||
|
import java.util.LinkedList; |
||||||
|
import java.util.Queue; |
||||||
|
|
||||||
|
import org.apache.activemq.transport.stomp.StompFrame; |
||||||
|
import org.apache.logging.log4j.LogManager; |
||||||
|
import org.apache.logging.log4j.Logger; |
||||||
|
import org.json.JSONArray; |
||||||
|
import org.json.JSONObject; |
||||||
|
import org.leolo.rail.model.LocationRecordType; |
||||||
|
import org.leolo.rail.model.ScheduleType; |
||||||
|
import org.leolo.rail.model.TrainSchedule; |
||||||
|
import org.leolo.rail.model.TrainScheduleLocation; |
||||||
|
|
||||||
|
public class VTSPProcessor extends Thread { |
||||||
|
private Logger log = LogManager.getLogger(VTSPProcessor.class); |
||||||
|
private Logger logRI = LogManager.getLogger("org.leolo.RI"); |
||||||
|
|
||||||
|
private final Object SYNC_TOKEN = new Object(); |
||||||
|
|
||||||
|
private Queue<StompFrame> procQueue = new LinkedList<>(); |
||||||
|
private boolean terminated = false; |
||||||
|
|
||||||
|
public void terminate() { |
||||||
|
terminated = true; |
||||||
|
synchronized(SYNC_TOKEN) { |
||||||
|
SYNC_TOKEN.notifyAll(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void process(StompFrame data) { |
||||||
|
procQueue.add(data); |
||||||
|
synchronized(SYNC_TOKEN) { |
||||||
|
SYNC_TOKEN.notifyAll(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
logRI.debug("Started."); |
||||||
|
while(true) { |
||||||
|
if(terminated) { |
||||||
|
return; |
||||||
|
} |
||||||
|
StompFrame data = procQueue.poll(); |
||||||
|
if(data==null) { |
||||||
|
synchronized(SYNC_TOKEN) { |
||||||
|
try { |
||||||
|
// log.debug("No more data. Sleep.");
|
||||||
|
SYNC_TOKEN.wait(1000); |
||||||
|
} catch (InterruptedException e) { |
||||||
|
log.error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
continue; |
||||||
|
} |
||||||
|
//Actually handle the data
|
||||||
|
String msgId = data.getHeaders().get("message-id"); |
||||||
|
log.info("Processing message {}", msgId); |
||||||
|
if(true||Constants.Generic.DEBUG_MODE) { |
||||||
|
new File("tmpd").mkdirs(); |
||||||
|
try(PrintWriter out = new PrintWriter("tmpd/VTSP-msg_"+msgId.replace(":", "-")+".json")){ |
||||||
|
out.println(data.getBody()); |
||||||
|
} catch (FileNotFoundException e) { |
||||||
|
log.error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
JSONObject obj = new JSONObject(data.getBody()).getJSONObject("VSTPCIFMsgV1").optJSONObject("schedule"); |
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); |
||||||
|
String txType = obj.optString("transaction_type"); |
||||||
|
if("Delete".equalsIgnoreCase(txType)) { |
||||||
|
//Remove the schedule
|
||||||
|
TrainSchedule ts = new TrainSchedule(); |
||||||
|
ts.setTrainUId(obj.optString("CIF_train_uid")); |
||||||
|
ts.setScheduleType(ScheduleType.STP); |
||||||
|
try { |
||||||
|
ts.setStartDate(sdf.parse(obj.optString("schedule_start_date"))); |
||||||
|
ts.setEndDate(sdf.parse(obj.optString("schedule_end_date"))); |
||||||
|
}catch(ParseException e) { |
||||||
|
log.atError().log(e.getMessage(), e); |
||||||
|
} |
||||||
|
try( |
||||||
|
Connection conn = DatabaseManager.getInstance().getConnection(); |
||||||
|
PreparedStatement psLoc = conn.prepareStatement("DELETE FROM stp_location WHERE suid = ?"); |
||||||
|
PreparedStatement psSch = conn.prepareStatement("DELETE FROM stp_schedule WHERE suid = ?"); |
||||||
|
){ |
||||||
|
psLoc.setString(1, ts.getSUID()); |
||||||
|
psSch.setString(1, ts.getSUID()); |
||||||
|
psLoc.executeUpdate(); |
||||||
|
psSch.executeUpdate(); |
||||||
|
conn.commit(); |
||||||
|
}catch(SQLException e) { |
||||||
|
log.error(e.getMessage(), e); |
||||||
|
} |
||||||
|
return; |
||||||
|
} |
||||||
|
try( |
||||||
|
Connection conn = DatabaseManager.getInstance().getConnection(); |
||||||
|
PreparedStatement psSch = conn.prepareStatement("INSERT INTO stp_schedule VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); |
||||||
|
PreparedStatement psLoc = conn.prepareStatement("INSERT INTO stp_location VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)") |
||||||
|
){ |
||||||
|
|
||||||
|
TrainSchedule ts = new TrainSchedule(); |
||||||
|
ts.setTrainUId(obj.optString("CIF_train_uid")); |
||||||
|
ts.setScheduleType(ScheduleType.STP); |
||||||
|
try { |
||||||
|
ts.setStartDate(sdf.parse(obj.optString("schedule_start_date"))); |
||||||
|
ts.setEndDate(sdf.parse(obj.optString("schedule_end_date"))); |
||||||
|
}catch(ParseException e) { |
||||||
|
log.atError().log(e.getMessage(), e); |
||||||
|
} |
||||||
|
ts.setDays(obj.optString("schedule_days_runs")); |
||||||
|
ts.setBankHolidayInd(obj.optString("CIF_bank_holiday_running")); |
||||||
|
ts.setSignalId(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("signalling_id")); |
||||||
|
ts.setRsid(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("CIF_headcode")); |
||||||
|
ts.setTrainStatus(obj.optString("train_status")); |
||||||
|
ts.setTrainCategory(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("CIF_train_category")); |
||||||
|
ts.setSection(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("CIF_business_sector")); |
||||||
|
ts.setPowerType(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("CIF_power_type")); |
||||||
|
ts.setTimingLoad(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("CIF_timing_load")); |
||||||
|
ts.setPlannedSpeed(Integer.toString((int) (obj.getJSONArray("schedule_segment").getJSONObject(0).optInt("CIF_speed")/2.24))); |
||||||
|
ts.setOperatingCharacter(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("CIF_operating_characteristics")); |
||||||
|
ts.setClassAvailable(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("CIF_train_class")); |
||||||
|
ts.setSleeper(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("CIF_sleepers")); |
||||||
|
ts.setReservation(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("CIF_reservations")); |
||||||
|
ts.setCatering(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("CIF_catering_code")); |
||||||
|
ts.setAtocCode(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("atoc_code")); |
||||||
|
JSONArray locs = obj.getJSONArray("schedule_segment").getJSONObject(0).getJSONArray("schedule_location"); |
||||||
|
for(int i=0;i<locs.length();i++) { |
||||||
|
JSONObject loc = locs.getJSONObject(i); |
||||||
|
TrainScheduleLocation tsl = new TrainScheduleLocation(); |
||||||
|
tsl.setTiplocCode(loc.getJSONObject("location").getJSONObject("tiploc").optString("tiploc_id")); |
||||||
|
tsl.setTiplocInstance(0); |
||||||
|
tsl.setArrival(getScheduleTime(loc.optString("scheduled_arrival_time"))); |
||||||
|
tsl.setDeparture(getScheduleTime(loc.optString("scheduled_departure_time"))); |
||||||
|
tsl.setPass(getScheduleTime(loc.optString("scheduled_pass_time"))); |
||||||
|
tsl.setPubArrival(getScheduleTime(loc.optString("public_arrival"))); |
||||||
|
tsl.setPubDeparture(getScheduleTime(loc.optString("public_departure"))); |
||||||
|
tsl.setPlatform(loc.optString("CIF_platform")); |
||||||
|
tsl.setLine(loc.optString("CIF_line")); |
||||||
|
tsl.setPath(loc.optString("CIF_path")); |
||||||
|
tsl.setEngineeringAllowance(getAllowanceTime(loc.optString("CIF_engineering_allowance"))); |
||||||
|
tsl.setPathingAllowance(getAllowanceTime(loc.optString("CIF_pathing_allowance"))); |
||||||
|
tsl.setPerformanceAllowance(getAllowanceTime(loc.optString("CIF_performance_allowance"))); |
||||||
|
// String locType = loc.optString("location_type");
|
||||||
|
if(i==0) { |
||||||
|
tsl.setRecordType(LocationRecordType.ORIGIN); |
||||||
|
}else if((i+1)==locs.length()) { |
||||||
|
tsl.setRecordType(LocationRecordType.TERMINATE); |
||||||
|
}else{ |
||||||
|
tsl.setRecordType(LocationRecordType.INTERMEDIATE); |
||||||
|
} |
||||||
|
ts.getLocations().add(tsl); |
||||||
|
} |
||||||
|
|
||||||
|
setString(psSch, 1, ts.getSUID()); |
||||||
|
setString(psSch, 2, ts.getTrainUId()); |
||||||
|
setString(psSch, 3, ts.getScheduleType().name()); |
||||||
|
setString(psSch, 4, sdf.format(ts.getStartDate())); |
||||||
|
setString(psSch, 5, sdf.format(ts.getEndDate())); |
||||||
|
setString(psSch, 6, ts.getDays()); |
||||||
|
setString(psSch, 7, ts.getBankHolidayInd()); |
||||||
|
setString(psSch, 8, ts.getSignalId()); |
||||||
|
setString(psSch, 9, ts.getRsid()); |
||||||
|
setString(psSch,10, ts.getTrainStatus()); |
||||||
|
setString(psSch,11, ts.getTrainCategory()); |
||||||
|
setString(psSch,12, ts.getSection()); |
||||||
|
setString(psSch,13, ts.getPowerType()); |
||||||
|
setString(psSch,14, ts.getTimingLoad()); |
||||||
|
setString(psSch,15, ts.getPlannedSpeed()); |
||||||
|
setString(psSch,16, ts.getOperatingCharacter()); |
||||||
|
setString(psSch,17, ts.getClassAvailable()); |
||||||
|
setString(psSch,18, ts.getSleeper()); |
||||||
|
setString(psSch,19, ts.getReservation()); |
||||||
|
setString(psSch,20, ts.getCatering()); |
||||||
|
setString(psSch,21, ts.getUicCode()); |
||||||
|
setString(psSch,22, ts.getAtocCode()); |
||||||
|
if(ts.getLocations().size()>1) { |
||||||
|
setString(psSch,23, ts.getLocations().get(0).getTiplocCode()); |
||||||
|
setTime(psSch,24, ts.getLocations().get(0).getDeparture()); |
||||||
|
setString(psSch,25, ts.getLocations().get(ts.getLocations().size()-1).getTiplocCode()); |
||||||
|
setTime(psSch,26, ts.getLocations().get(ts.getLocations().size()-1).getArrival()); |
||||||
|
}else { |
||||||
|
psSch.setNull(23, Types.CHAR); |
||||||
|
psSch.setNull(24, Types.TIME); |
||||||
|
psSch.setNull(25, Types.CHAR); |
||||||
|
psSch.setNull(26, Types.TIME); |
||||||
|
} |
||||||
|
psSch.setInt(27, ts.hashCode()); |
||||||
|
int seq = 1; |
||||||
|
for(TrainScheduleLocation tsl:ts.getLocations()) { |
||||||
|
setString(psLoc, 1, ts.getSUID()); |
||||||
|
psLoc.setInt(2, seq++); |
||||||
|
setString(psLoc, 3, tsl.getTiplocCode()); |
||||||
|
psLoc.setInt(4, tsl.getTiplocInstance()); |
||||||
|
setTime(psLoc, 5, tsl.getArrival()); |
||||||
|
setTime(psLoc, 6, tsl.getDeparture()); |
||||||
|
setTime(psLoc, 7, tsl.getPass()); |
||||||
|
setTime(psLoc, 8, tsl.getPubArrival()); |
||||||
|
setTime(psLoc, 9, tsl.getPubDeparture()); |
||||||
|
setString(psLoc,10, tsl.getPlatform()); |
||||||
|
setString(psLoc,11, tsl.getLine()); |
||||||
|
setString(psLoc,12, tsl.getPath()); |
||||||
|
setTime(psLoc,13, tsl.getEngineeringAllowance()); |
||||||
|
setTime(psLoc,14, tsl.getPathingAllowance()); |
||||||
|
setTime(psLoc,15, tsl.getPerformanceAllowance()); |
||||||
|
setString(psLoc,16, tsl.getRecordType().getRecordCode()); |
||||||
|
psLoc.addBatch(); |
||||||
|
} |
||||||
|
psSch.executeUpdate(); |
||||||
|
psLoc.executeBatch(); |
||||||
|
conn.commit(); |
||||||
|
}catch(SQLException e) { |
||||||
|
log.atError().log(e.getMessage(),e); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected void setString(PreparedStatement stmt, int col, String val) throws SQLException{ |
||||||
|
if(val==null||"".equals(val)) { |
||||||
|
stmt.setNull(col, Types.CHAR); |
||||||
|
}else { |
||||||
|
stmt.setString(col, val); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private long getScheduleTime(String t) { |
||||||
|
//HHMMSS
|
||||||
|
t = t.trim(); |
||||||
|
if("".equals(t)) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
int hour = Integer.parseInt(t.substring(0, 2)); |
||||||
|
int min = Integer.parseInt(t.substring(2, 4)); |
||||||
|
int sec = Integer.parseInt(t.substring(4, 6)); |
||||||
|
return hour*3_600_000+min*60_000+sec; |
||||||
|
} |
||||||
|
|
||||||
|
private long getAllowanceTime(String t) { |
||||||
|
if("".equals(t.trim())) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
if("H".equals(t.trim())) |
||||||
|
return 30_000; |
||||||
|
if(t.endsWith("H")) { |
||||||
|
//nH
|
||||||
|
return Integer.parseInt(t.substring(0,1))*60_000+30_000; |
||||||
|
}else { |
||||||
|
//nn
|
||||||
|
return Integer.parseInt(t)*60_000; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void setTime(PreparedStatement stmt, int col, long time) throws SQLException{ |
||||||
|
if(time==0) { |
||||||
|
stmt.setNull(col, Types.TIME); |
||||||
|
}else { |
||||||
|
int h = (int)(time/3_600_000); |
||||||
|
int m = (int)((time/60_000)%60); |
||||||
|
int s = (int)((time/1_000)%60); |
||||||
|
stmt.setString(col, h+":"+m+":"+s); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue