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