Omaha #4522 Add proper primary key to active table

Change-Id: Id1c6f4ce0b317211e3a1eed0240f2463bd842f40

Former-commit-id: 99243fee7951395b37730327a19c6391832cbc36
This commit is contained in:
Ron Anderson 2015-05-26 18:37:42 -05:00
parent 4f3ceac99b
commit f7d30d71bd
15 changed files with 498 additions and 159 deletions

View file

@ -0,0 +1,18 @@
<included>
<!-- activeTableChange log -->
<appender name="activeTableChangeLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="com.raytheon.uf.common.status.logback.StdTimeBasedRollingPolicy">
<name>activeTableChange</name>
</rollingPolicy>
<encoder class="com.raytheon.uf.common.status.logback.UFStdEncoder"/>
</appender>
<appender name="activeTableChangeLogAsync" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="activeTableChangeLog" />
</appender>
<logger name="ActiveTableChange" additivity="false">
<level value="DEBUG"/>
<appender-ref ref="activeTableChangeLogAsync" />
</logger>
</included>

View file

@ -11,16 +11,7 @@
</appender>
<!-- activeTableChange log -->
<appender name="activeTableChangeLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="com.raytheon.uf.common.status.logback.StdTimeBasedRollingPolicy">
<name>activeTableChange</name>
</rollingPolicy>
<encoder class="com.raytheon.uf.common.status.logback.UFStdEncoder"/>
</appender>
<appender name="activeTableChangeLogAsync" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="activeTableChangeLog" />
</appender>
<include file="${edex.home}/conf/logback-activeTableChange.xml"/>
<!-- Purge log -->
<appender name="purge" class="ch.qos.logback.core.rolling.RollingFileAppender">
@ -89,11 +80,6 @@
<include file="${edex.home}/conf/logback-edex-limited-loggers.xml"/>
<include file="${edex.home}/conf/logback-edex-hibernate-logger.xml"/>
<logger name="ActiveTableChange" additivity="false">
<level value="DEBUG"/>
<appender-ref ref="activeTableChangeLogAsync" />
</logger>
<logger name="com.raytheon.edex.plugin.shef" additivity="false">
<level value="INFO"/>
<appender-ref ref="shef" />

View file

@ -60,6 +60,10 @@
<logger name="org.hibernate">
<level value="ERROR"/>
</logger>
<!-- activeTableChange log -->
<include file="${edex.home}/conf/logback-activeTableChange.xml"/>
<!-- default logging -->
<root>
<level value="INFO"/>

View file

@ -5,24 +5,6 @@
<include file="${edex.home}/conf/logback-edex-loggers.xml" />
<include file="${edex.home}/conf/logback-edex-hibernate-logger.xml" />
<!-- activeTableChange log -->
<appender name="activeTableChangeLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="com.raytheon.uf.common.status.logback.StdTimeBasedRollingPolicy">
<name>activeTableChange</name>
</rollingPolicy>
<encoder class="com.raytheon.uf.common.status.logback.UFStdEncoder"/>
</appender>
<appender name="activeTableChangeLogAsync" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="activeTableChangeLog" />
</appender>
<logger name="ActiveTableChange" additivity="false">
<level value="DEBUG"/>
<appender-ref ref="activeTableChangeLogAsync" />
</logger>
<!-- default logging -->
<root>
<level value="INFO"/>

View file

@ -0,0 +1,3 @@
#!/bin/bash
psql -h dx1 -U awips -d metadata -n awips -f updateActiveTable.sql

View file

@ -0,0 +1,94 @@
BEGIN;
-- first remove any duplicate records
DROP TABLE IF EXISTS t_deleteIds;
CREATE TEMP TABLE t_deleteIds (id int);
INSERT INTO t_deleteIds(id) (
SELECT id FROM (
SELECT id,
ROW_NUMBER() OVER(PARTITION BY officeid, phen, sig, etn, ugczone ORDER BY issuetime DESC) AS Row
FROM activetable
) dups
WHERE dups.Row > 1);
DELETE FROM activetable a using t_deleteIds t WHERE a.id = t.id;
COMMIT;
BEGIN;
-- drop the old id column as primary key
ALTER TABLE activetable DROP CONSTRAINT IF EXISTS activetable_pkey;
ALTER TABLE activetable DROP COLUMN IF EXISTS id;
DROP SEQUENCE IF EXISTS activetableseq;
-- set proper length on several columns
ALTER TABLE activetable ALTER COLUMN act TYPE character varying(3);
ALTER TABLE activetable ALTER COLUMN wmoid TYPE character varying(22);
ALTER TABLE activetable ALTER COLUMN vtecstr TYPE character varying(48);
ALTER TABLE activetable ALTER COLUMN productclass TYPE character varying(1);
ALTER TABLE activetable ALTER COLUMN locationid TYPE character varying(5);
ALTER TABLE activetable ALTER COLUMN floodseverity TYPE character varying(1);
ALTER TABLE activetable ALTER COLUMN immediatecause TYPE character varying(2);
ALTER TABLE activetable ALTER COLUMN officeid TYPE character varying(4);
ALTER TABLE activetable ALTER COLUMN phen TYPE character varying(2);
ALTER TABLE activetable ALTER COLUMN sig TYPE character varying(1);
ALTER TABLE activetable ALTER COLUMN ugczone TYPE character varying(6);
-- add new primary key
ALTER TABLE activetable ALTER COLUMN officeid SET NOT NULL;
ALTER TABLE activetable ALTER COLUMN phen SET NOT NULL;
ALTER TABLE activetable ALTER COLUMN sig SET NOT NULL;
ALTER TABLE activetable ALTER COLUMN etn SET NOT NULL;
ALTER TABLE activetable ALTER COLUMN ugczone SET NOT NULL;
ALTER TABLE activetable ADD CONSTRAINT activetable_pkey PRIMARY KEY (etn, officeid, phen, sig, ugczone);
COMMIT;
VACUUM FULL ANALYZE activetable;
-- now do the same for the practice_activetable
BEGIN;
-- first remove any duplicate records
DROP TABLE IF EXISTS t_deleteIds;
CREATE TEMP TABLE t_deleteIds (id int);
INSERT INTO t_deleteIds(id) (
SELECT id FROM (
SELECT id,
ROW_NUMBER() OVER(PARTITION BY officeid, phen, sig, etn, ugczone ORDER BY issuetime DESC) AS Row
FROM practice_activetable
) dups
WHERE dups.Row > 1);
DELETE FROM practice_activetable a using t_deleteIds t WHERE a.id = t.id;
COMMIT;
BEGIN;
-- drop the old id column as primary key
ALTER TABLE practice_activetable DROP CONSTRAINT IF EXISTS practice_activetable_pkey;
ALTER TABLE practice_activetable DROP COLUMN IF EXISTS id;
DROP SEQUENCE IF EXISTS practice_activetableseq;
-- set proper length on several columns
ALTER TABLE practice_activetable ALTER COLUMN act TYPE character varying(3);
ALTER TABLE practice_activetable ALTER COLUMN wmoid TYPE character varying(22);
ALTER TABLE practice_activetable ALTER COLUMN vtecstr TYPE character varying(48);
ALTER TABLE practice_activetable ALTER COLUMN productclass TYPE character varying(1);
ALTER TABLE practice_activetable ALTER COLUMN locationid TYPE character varying(5);
ALTER TABLE practice_activetable ALTER COLUMN floodseverity TYPE character varying(1);
ALTER TABLE practice_activetable ALTER COLUMN immediatecause TYPE character varying(2);
ALTER TABLE practice_activetable ALTER COLUMN officeid TYPE character varying(4);
ALTER TABLE practice_activetable ALTER COLUMN phen TYPE character varying(2);
ALTER TABLE practice_activetable ALTER COLUMN sig TYPE character varying(1);
ALTER TABLE practice_activetable ALTER COLUMN ugczone TYPE character varying(6);
-- add new primary key
ALTER TABLE practice_activetable ALTER COLUMN officeid SET NOT NULL;
ALTER TABLE practice_activetable ALTER COLUMN phen SET NOT NULL;
ALTER TABLE practice_activetable ALTER COLUMN sig SET NOT NULL;
ALTER TABLE practice_activetable ALTER COLUMN etn SET NOT NULL;
ALTER TABLE practice_activetable ALTER COLUMN ugczone SET NOT NULL;
ALTER TABLE practice_activetable ADD CONSTRAINT practice_activetable_pkey PRIMARY KEY (etn, officeid, phen, sig, ugczone);
COMMIT;
VACUUM FULL ANALYZE practice_activetable;
DROP TABLE IF EXISTS t_deleteIds;

View file

@ -0,0 +1,228 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.activetable;
import javax.persistence.Column;
import com.raytheon.uf.common.dataplugin.annotations.DataURI;
import com.raytheon.uf.common.dataplugin.persist.PersistableDataObject;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
/**
* Primary key for ActiveTableRecord
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 05/22/2015 4522 randerso Create proper primary key for ActiveTableRecord
*
* </pre>
*
* @author randerso
* @version 1.0
*/
public class ActiveTableKey extends PersistableDataObject {
@Column(length = 4)
@DynamicSerializeElement
protected String officeid;
@Column(length = 2)
@DynamicSerializeElement
protected String phen;
@Column(length = 1)
@DynamicSerializeElement
protected String sig;
@DataURI(position = 5)
@Column(length = 4)
@DynamicSerializeElement
protected String etn;
@Column(length = 6)
@DynamicSerializeElement
protected String ugcZone;
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = (prime * result) + ((etn == null) ? 0 : etn.hashCode());
result = (prime * result)
+ ((officeid == null) ? 0 : officeid.hashCode());
result = (prime * result) + ((phen == null) ? 0 : phen.hashCode());
result = (prime * result) + ((sig == null) ? 0 : sig.hashCode());
result = (prime * result)
+ ((ugcZone == null) ? 0 : ugcZone.hashCode());
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
ActiveTableKey other = (ActiveTableKey) obj;
if (etn == null) {
if (other.etn != null) {
return false;
}
} else if (!etn.equals(other.etn)) {
return false;
}
if (officeid == null) {
if (other.officeid != null) {
return false;
}
} else if (!officeid.equals(other.officeid)) {
return false;
}
if (phen == null) {
if (other.phen != null) {
return false;
}
} else if (!phen.equals(other.phen)) {
return false;
}
if (sig == null) {
if (other.sig != null) {
return false;
}
} else if (!sig.equals(other.sig)) {
return false;
}
if (ugcZone == null) {
if (other.ugcZone != null) {
return false;
}
} else if (!ugcZone.equals(other.ugcZone)) {
return false;
}
return true;
}
/**
* @return the officeid
*/
public String getOfficeid() {
return officeid;
}
/**
* @param officeid
* the officeid to set
*/
public void setOfficeid(String officeid) {
this.officeid = officeid;
}
/**
* @return the phen
*/
public String getPhen() {
return phen;
}
/**
* @param phen
* the phen to set
*/
public void setPhen(String phen) {
this.phen = phen;
}
/**
* @return the sig
*/
public String getSig() {
return sig;
}
/**
* @param sig
* the sig to set
*/
public void setSig(String sig) {
this.sig = sig;
}
/**
* @return the etn
*/
public String getEtn() {
return etn;
}
/**
* @param etn
* the etn to set
*/
public void setEtn(String etn) {
this.etn = etn;
}
/**
* @return the ugcZone
*/
public String getUgcZone() {
return ugcZone;
}
/**
* @param ugcZone
* the ugcZone to set
*/
public void setUgcZone(String ugcZone) {
this.ugcZone = ugcZone;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getOfficeid()).append(".").append(getPhen()).append(".")
.append(getSig()).append(".").append(getEtn()).append(" ")
.append(getUgcZone());
return sb.toString();
}
}

View file

@ -25,9 +25,7 @@ import java.util.Date;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.EmbeddedId;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.MappedSuperclass;
@ -58,6 +56,7 @@ import com.vividsolutions.jts.geom.Geometry;
* spatial
* 10/16/2014 3454 bphillip Upgrading to Hibernate 4
* 04/28/2015 4027 randerso Expunged Calendar from ActiveTableRecord
* 05/22/2015 4522 randerso Create proper primary key for ActiveTableRecord
* </pre>
*
* @author njensen
@ -66,17 +65,15 @@ import com.vividsolutions.jts.geom.Geometry;
@MappedSuperclass
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@DynamicSerialize
// TODO: do we get anything from extending PersistableDataObject here?
public abstract class ActiveTableRecord extends PersistableDataObject {
protected static final long serialVersionUID = 1L;
protected static final String ID_GEN = "idgen";
@EmbeddedId
@DynamicSerializeElement
protected ActiveTableKey key;
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = ID_GEN)
@Id
protected int id;
@Column(length = 32)
@Column(length = 22)
@DynamicSerializeElement
protected String wmoid;
@ -92,40 +89,19 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
@DynamicSerializeElement
protected String countyheader;
@Column(length = 8)
@DynamicSerializeElement
protected String ugcZone;
@Column(columnDefinition = "text")
@Column(length = 48)
@DynamicSerializeElement
protected String vtecstr;
@Column(length = 4)
@Column(length = 1)
@DynamicSerializeElement
protected String productClass;
@DataURI(position = 4)
@Column(length = 4)
@Column(length = 3)
@DynamicSerializeElement
protected String act;
@Column(length = 8)
@DynamicSerializeElement
protected String officeid;
@Column(length = 4)
@DynamicSerializeElement
protected String phen;
@Column(length = 4)
@DynamicSerializeElement
protected String sig;
@DataURI(position = 5)
@Column(length = 4)
@DynamicSerializeElement
protected String etn;
/** vtec start time */
@DynamicSerializeElement
protected Date startTime;
@ -142,7 +118,7 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
@DynamicSerializeElement
protected Date purgeTime;
@Column(length = 8)
@Column
@DynamicSerializeElement
protected boolean ufn;
@ -163,6 +139,7 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
@DynamicSerializeElement
protected Integer motspd;
// TODO: make this column a Geometry
@Column(columnDefinition = "text")
@DynamicSerializeElement
protected String loc;
@ -194,14 +171,15 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
@DynamicSerializeElement
protected String segText;
@Column(length = 8)
@Column(length = 5)
@DynamicSerializeElement
protected String locationID;
@Column(length = 2)
@Column(length = 1)
@DynamicSerializeElement
protected String floodSeverity;
@Column(length = 2)
@DynamicSerializeElement
protected String immediateCause;
@ -221,9 +199,18 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
@DynamicSerializeElement
protected Date floodEnd;
public ActiveTableRecord() {
this.key = new ActiveTableKey();
}
@Override
public abstract Object clone();
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
@ -257,13 +244,6 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
} else if (!endTime.equals(other.endTime)) {
return false;
}
if (etn == null) {
if (other.etn != null) {
return false;
}
} else if (!etn.equals(other.etn)) {
return false;
}
if (floodBegin == null) {
if (other.floodBegin != null) {
return false;
@ -310,7 +290,7 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
if (other.geometry != null) {
return false;
}
} else if (!geometry.equalsExact(other.geometry)) {
} else if (!geometry.equals(other.geometry)) {
return false;
}
if (immediateCause == null) {
@ -327,6 +307,13 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
} else if (!issueTime.equals(other.issueTime)) {
return false;
}
if (key == null) {
if (other.key != null) {
return false;
}
} else if (!key.equals(other.key)) {
return false;
}
if (loc == null) {
if (other.loc != null) {
return false;
@ -355,13 +342,6 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
} else if (!motspd.equals(other.motspd)) {
return false;
}
if (officeid == null) {
if (other.officeid != null) {
return false;
}
} else if (!officeid.equals(other.officeid)) {
return false;
}
if (overviewText == null) {
if (other.overviewText != null) {
return false;
@ -369,13 +349,6 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
} else if (!overviewText.equals(other.overviewText)) {
return false;
}
if (phen == null) {
if (other.phen != null) {
return false;
}
} else if (!phen.equals(other.phen)) {
return false;
}
if (phensig == null) {
if (other.phensig != null) {
return false;
@ -428,13 +401,6 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
} else if (!segText.equals(other.segText)) {
return false;
}
if (sig == null) {
if (other.sig != null) {
return false;
}
} else if (!sig.equals(other.sig)) {
return false;
}
if (startTime == null) {
if (other.startTime != null) {
return false;
@ -445,13 +411,6 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
if (ufn != other.ufn) {
return false;
}
if (ugcZone == null) {
if (other.ugcZone != null) {
return false;
}
} else if (!ugcZone.equals(other.ugcZone)) {
return false;
}
if (vtecstr == null) {
if (other.vtecstr != null) {
return false;
@ -476,6 +435,21 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
return true;
}
/**
* @return the key
*/
public ActiveTableKey getKey() {
return key;
}
/**
* @param key
* the key to set
*/
public void setKey(ActiveTableKey key) {
this.key = key;
}
/**
* @return the wmoid
*/
@ -540,7 +514,7 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
* @return the ugcZone
*/
public String getUgcZone() {
return ugcZone;
return key.ugcZone;
}
/**
@ -548,7 +522,7 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
* the ugcZone to set
*/
public void setUgcZone(String ugcZone) {
this.ugcZone = ugcZone;
this.key.ugcZone = ugcZone;
}
/**
@ -600,7 +574,7 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
* @return the officeid
*/
public String getOfficeid() {
return officeid;
return key.officeid;
}
/**
@ -608,14 +582,14 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
* the officeid to set
*/
public void setOfficeid(String officeid) {
this.officeid = officeid;
this.key.officeid = officeid;
}
/**
* @return the phen
*/
public String getPhen() {
return phen;
return key.phen;
}
/**
@ -623,14 +597,14 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
* the phen to set
*/
public void setPhen(String phen) {
this.phen = phen;
this.key.phen = phen;
}
/**
* @return the sig
*/
public String getSig() {
return sig;
return key.sig;
}
/**
@ -638,14 +612,14 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
* the sig to set
*/
public void setSig(String sig) {
this.sig = sig;
this.key.sig = sig;
}
/**
* @return the etn
*/
public String getEtn() {
return etn;
return key.etn;
}
/**
@ -653,7 +627,7 @@ public abstract class ActiveTableRecord extends PersistableDataObject {
* the etn to set
*/
public void setEtn(String etn) {
this.etn = etn;
this.key.etn = etn;
}
/**

View file

@ -20,7 +20,6 @@
package com.raytheon.uf.common.activetable;
import javax.persistence.Entity;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.hibernate.annotations.Index;
@ -28,7 +27,8 @@ import org.hibernate.annotations.Index;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
/**
* Operational Active Table, separated so that practice and operational data go to separate tables.
* Operational Active Table, separated so that practice and operational data go
* to separate tables.
*
* <pre>
*
@ -37,6 +37,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
* ------------ ---------- ----------- --------------------------
* Feb 10, 2010 njensen Initial creation
* May 10, 2013 1951 rjpeter Added own id sequence tagging and new index.
* May 22, 2015 4522 randerso Create proper primary key for ActiveTableRecord
* </pre>
*
* @author njensen
@ -44,7 +45,6 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
*/
@Entity
@SequenceGenerator(initialValue = 1, name = ActiveTableRecord.ID_GEN, sequenceName = "activetableseq")
@Table(name = "activetable")
@DynamicSerialize
@org.hibernate.annotations.Table(appliesTo = "activetable", indexes = { @Index(name = "activetable_officeid_phensig_idx", columnNames = {

View file

@ -20,7 +20,6 @@
package com.raytheon.uf.common.activetable;
import javax.persistence.Entity;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.hibernate.annotations.Index;
@ -28,7 +27,8 @@ import org.hibernate.annotations.Index;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
/**
* Practice Active Table, separated so that practice and operational data go to separate tables.
* Practice Active Table, separated so that practice and operational data go to
* separate tables.
*
* <pre>
*
@ -37,6 +37,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
* ------------ ---------- ----------- --------------------------
* Feb 10, 2010 njensen Initial creation
* May 10, 2013 1951 rjpeter Added own id sequence tagging and new index.
* May 22, 2015 4522 randerso Create proper primary key for ActiveTableRecord
* </pre>
*
* @author njensen
@ -44,7 +45,6 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
*/
@Entity
@SequenceGenerator(initialValue = 1, name = ActiveTableRecord.ID_GEN, sequenceName = "practice_activetableseq")
@Table(name = "practice_activetable")
@DynamicSerialize
@org.hibernate.annotations.Table(appliesTo = "practice_activetable", indexes = { @Index(name = "practice_activetable_officeid_phensig_idx", columnNames = {

View file

@ -2,4 +2,5 @@ source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
res/
res/,\
utility/

View file

@ -20,6 +20,7 @@
package com.raytheon.uf.edex.activetable;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
@ -27,14 +28,17 @@ import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import jep.JepException;
import org.apache.log4j.Logger;
import org.hibernate.NonUniqueObjectException;
import com.raytheon.edex.site.SiteUtil;
import com.raytheon.uf.common.activetable.ActiveTableKey;
import com.raytheon.uf.common.activetable.ActiveTableMode;
import com.raytheon.uf.common.activetable.ActiveTableRecord;
import com.raytheon.uf.common.activetable.MergeResult;
@ -111,6 +115,7 @@ import com.raytheon.uf.edex.database.query.DatabaseQuery;
* Mar 04, 2015 4129 randerso Pass active table change logger to ingestAt and/or MergeVTEC
* Apr 28, 2015 #4027 randerso Expunged Calendar from ActiveTableRecord,
* fixed next ETN query to query for >= Jan 1
* May 22, 2015 4522 randerso Create proper primary key for ActiveTableRecord
*
* </pre>
*
@ -362,7 +367,7 @@ public class ActiveTable {
perfStat.logDuration("filterTable", timer.getElapsedTime());
timer.reset();
timer.start();
updateTable(siteId, result, mode);
updateTable(result, mode);
timer.stop();
perfStat.logDuration("updateTable", timer.getElapsedTime());
} finally {
@ -472,7 +477,7 @@ public class ActiveTable {
}
if (etn != null) {
query.addQueryParam("etn", etn, "in");
query.addQueryParam("key.etn", etn, "in");
}
if (requestValidTimes && (currentTime != null)) {
@ -491,7 +496,7 @@ public class ActiveTable {
query.setMaxResults(1);
}
query.addQueryParam("officeid", siteId, "in");
query.addQueryParam("key.officeid", siteId, "in");
List<ActiveTableRecord> result = null;
try {
@ -504,21 +509,62 @@ public class ActiveTable {
}
/**
* Replaces the active table for the site with the new active table
* Updates the active table
*
* @param siteId
* the four letter site id to replace
* @param changes
* the updated table followed by the purged records
*/
private static void updateTable(String siteId, MergeResult changes,
ActiveTableMode mode) {
private static void updateTable(MergeResult changes, ActiveTableMode mode) {
List<ActiveTableRecord> updated = changes.updatedList;
List<ActiveTableRecord> purged = changes.purgedList;
// Check for multiple updates for the same active table key
Map<ActiveTableKey, ActiveTableRecord> updatesMap = new HashMap<>(
updated.size(), 1.0f);
for (ActiveTableRecord rec : updated) {
ActiveTableRecord prevRec = updatesMap.get(rec.getKey());
// if multiple updates select the one with the latest issueTime
if ((prevRec == null)
|| rec.getIssueTime().after(prevRec.getIssueTime())) {
updatesMap.put(rec.getKey(), rec);
if (prevRec != null) {
statusHandler.warn("Multiple updates received for: "
+ rec.getKey().toString() + "\n "
+ prevRec.getVtecstr() + " " + prevRec.getUgcZone()
+ "\n " + rec.getVtecstr() + " "
+ rec.getUgcZone());
}
}
}
// Don't try to delete purged records that are being updated
List<ActiveTableRecord> toDelete = new ArrayList<>(purged.size());
for (ActiveTableRecord rec : purged) {
if (!updatesMap.containsKey(rec.getKey())) {
toDelete.add(rec);
}
}
CoreDao dao = (ActiveTableMode.OPERATIONAL.equals(mode)) ? operationalDao
: practiceDao;
dao.bulkSaveOrUpdateAndDelete(updated, purged);
try {
dao.bulkSaveOrUpdateAndDelete(updated, toDelete);
} catch (NonUniqueObjectException e) {
StringBuilder msg = new StringBuilder(
"Error saving updates to activetable\nUpdates:");
for (ActiveTableRecord rec : updated) {
msg.append("\n").append(rec.getAct()).append(" ")
.append(rec.getKey());
}
msg.append("\nDeletes:");
for (ActiveTableRecord rec : toDelete) {
msg.append("\n").append(rec.getAct()).append(" ")
.append(rec.getKey());
}
statusHandler.error(msg.toString(), e);
}
}
/**
@ -657,7 +703,7 @@ public class ActiveTable {
}
if (result != null) {
updateTable(siteId, result, tableName);
updateTable(result, tableName);
}
} finally {
if (writeLock != null) {

View file

@ -33,6 +33,7 @@
# to a separate thread in java.
# Added performance logging
# 02/05/15 #4099 randerso Changed log level of year-end issuance tweak
# May 22, 2015 4522 randerso Create proper primary key for ActiveTableRecord
#
import time
@ -53,8 +54,9 @@ perfStat = PerformanceStatus.getHandler("ActiveTable")
class ActiveTable(VTECTableUtil.VTECTableUtil):
def __init__(self, activeTableMode):
def __init__(self, activeTableMode, logger=None):
self._time = time.time()
self._logger = logger
# create a dummy name to simplify the file access code in VTECTableUtil
pathMgr = PathManagerFactory.getPathManager()
@ -218,6 +220,7 @@ class ActiveTable(VTECTableUtil.VTECTableUtil):
"OldRec: ", self.printEntry(rec),
"\nReassign action to: ", rec['act'])
newR['act'] = rec['act']
rec['state'] = "Replaced"
break
#due to above code, this should never execute
if newR['act'] == "COR":
@ -280,12 +283,11 @@ class ActiveTable(VTECTableUtil.VTECTableUtil):
#strip out the "state" field
outTable = []
for r in updatedTable:
if r['state'] not in ["Replaced", "Purged"]:
del r['state']
outTable.append(r)
if r['state'] == "Purged":
purgedRecords.append(r)
else:
purgedRecords.append(r)
outTable.append(r)
return outTable, purgedRecords, changes, changedFlag
def mergeFromJava(siteId, activeTable, newRecords, logger, mode, offsetSecs=0):
@ -304,7 +306,7 @@ def mergeFromJava(siteId, activeTable, newRecords, logger, mode, offsetSecs=0):
rec = ActiveTableRecord.ActiveTableRecord(newRecords.get(i))
pyNew.append(rec)
active = ActiveTable(mode)
active = ActiveTable(mode, logger)
logger.info("Updating " + mode + " Active Table: new records\n" +
active.printActiveTable(pyNew, combine=1))
@ -321,29 +323,29 @@ def mergeFromJava(siteId, activeTable, newRecords, logger, mode, offsetSecs=0):
logger.info("Updated " + mode + " Active Table: purged\n" +
active.printActiveTable(purgeRecords, combine=1))
replaced = []
decoded = []
other = []
stateDict = {}
for r in updatedTable:
if r['state'] == "Replaced":
replaced.append(r)
elif r['state'] == "Decoded":
decoded.append(r)
else:
other.append(r)
recs = stateDict.get(r['state'], [])
recs.append(r)
stateDict[r['state']] = recs
keys = stateDict.keys()
keys.sort()
for key in keys:
if key == "Previous":
continue
logger.info("Updated " + mode + " Active Table: replaced\n" +
active.printActiveTable(replaced, combine=1))
logger.info("Updated " + mode + " Active Table: decoded\n" +
active.printActiveTable(decoded, combine=1))
logger.info("Updated " + mode + " Active Table: "+ key +"\n" +
active.printActiveTable(stateDict[key], combine=1))
updatedList = ArrayList(len(updatedTable))
for x in updatedTable:
updatedList.add(x.javaRecord())
for r in updatedTable:
if r['state'] not in ["Previous", "Replaced"]:
updatedList.add(r.javaRecord())
purgedList = ArrayList(len(purgeRecords))
for x in purgeRecords:
purgedList.add(x.javaRecord())
for r in purgeRecords:
purgedList.add(r.javaRecord())
changeList = ArrayList(len(changes))
if (changedFlag):

View file

@ -31,6 +31,7 @@
# __ne__().
# 07/23/13 2212 dgilling Fix typo in __eq__().
# 04/28/2015 4027 randerso Expunged Calendar from ActiveTableRecord
# 05/22/2015 4522 randerso Create proper primary key for ActiveTableRecord
#
#
@ -145,6 +146,7 @@ class ActiveTableRecord(object):
raise KeyError
def __delitem__(self, key):
# TODO: implement this
pass
def __deepcopy__(self, memo):

View file

@ -37,6 +37,7 @@
# 05/15/14 #3157 dgilling Support multiple TPC and SPC sites.
# 03/04/2015 #4129 randerso Log the active table changes at info level
# in the active table change log
# May 22, 2015 4522 randerso Create proper primary key for ActiveTableRecord
#
##
@ -370,8 +371,6 @@ class MergeVTEC(VTECTableUtil.VTECTableUtil):
self.printActiveTable(ignoredOldReplaceAct, 1))
atChangeLog.info("Table Changes: " + str(changes))
purges.extend(oldReplaceEntriesAct)
purges.extend(oldReplaceEntriesPast)
return activeTable, purges, changes
def getMergeResults(self):