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 d29a908bdd
commit 75c224ead5
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> </appender>
<!-- activeTableChange log --> <!-- activeTableChange log -->
<appender name="activeTableChangeLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> <include file="${edex.home}/conf/logback-activeTableChange.xml"/>
<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>
<!-- Purge log --> <!-- Purge log -->
<appender name="purge" class="ch.qos.logback.core.rolling.RollingFileAppender"> <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-limited-loggers.xml"/>
<include file="${edex.home}/conf/logback-edex-hibernate-logger.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"> <logger name="com.raytheon.edex.plugin.shef" additivity="false">
<level value="INFO"/> <level value="INFO"/>
<appender-ref ref="shef" /> <appender-ref ref="shef" />

View file

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

View file

@ -20,7 +20,6 @@
package com.raytheon.uf.common.activetable; package com.raytheon.uf.common.activetable;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table; import javax.persistence.Table;
import org.hibernate.annotations.Index; import org.hibernate.annotations.Index;
@ -28,7 +27,8 @@ import org.hibernate.annotations.Index;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; 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> * <pre>
* *
@ -37,6 +37,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Feb 10, 2010 njensen Initial creation * Feb 10, 2010 njensen Initial creation
* May 10, 2013 1951 rjpeter Added own id sequence tagging and new index. * 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> * </pre>
* *
* @author njensen * @author njensen
@ -44,7 +45,6 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
*/ */
@Entity @Entity
@SequenceGenerator(initialValue = 1, name = ActiveTableRecord.ID_GEN, sequenceName = "activetableseq")
@Table(name = "activetable") @Table(name = "activetable")
@DynamicSerialize @DynamicSerialize
@org.hibernate.annotations.Table(appliesTo = "activetable", indexes = { @Index(name = "activetable_officeid_phensig_idx", columnNames = { @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; package com.raytheon.uf.common.activetable;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table; import javax.persistence.Table;
import org.hibernate.annotations.Index; import org.hibernate.annotations.Index;
@ -28,7 +27,8 @@ import org.hibernate.annotations.Index;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; 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> * <pre>
* *
@ -37,6 +37,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Feb 10, 2010 njensen Initial creation * Feb 10, 2010 njensen Initial creation
* May 10, 2013 1951 rjpeter Added own id sequence tagging and new index. * 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> * </pre>
* *
* @author njensen * @author njensen
@ -44,7 +45,6 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
*/ */
@Entity @Entity
@SequenceGenerator(initialValue = 1, name = ActiveTableRecord.ID_GEN, sequenceName = "practice_activetableseq")
@Table(name = "practice_activetable") @Table(name = "practice_activetable")
@DynamicSerialize @DynamicSerialize
@org.hibernate.annotations.Table(appliesTo = "practice_activetable", indexes = { @Index(name = "practice_activetable_officeid_phensig_idx", columnNames = { @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/ output.. = bin/
bin.includes = META-INF/,\ bin.includes = META-INF/,\
.,\ .,\
res/ res/,\
utility/

View file

@ -20,6 +20,7 @@
package com.raytheon.uf.edex.activetable; package com.raytheon.uf.edex.activetable;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collection; import java.util.Collection;
@ -27,14 +28,17 @@ import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TimeZone; import java.util.TimeZone;
import jep.JepException; import jep.JepException;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.hibernate.NonUniqueObjectException;
import com.raytheon.edex.site.SiteUtil; 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.ActiveTableMode;
import com.raytheon.uf.common.activetable.ActiveTableRecord; import com.raytheon.uf.common.activetable.ActiveTableRecord;
import com.raytheon.uf.common.activetable.MergeResult; 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 * Mar 04, 2015 4129 randerso Pass active table change logger to ingestAt and/or MergeVTEC
* Apr 28, 2015 #4027 randerso Expunged Calendar from ActiveTableRecord, * Apr 28, 2015 #4027 randerso Expunged Calendar from ActiveTableRecord,
* fixed next ETN query to query for >= Jan 1 * fixed next ETN query to query for >= Jan 1
* May 22, 2015 4522 randerso Create proper primary key for ActiveTableRecord
* *
* </pre> * </pre>
* *
@ -362,7 +367,7 @@ public class ActiveTable {
perfStat.logDuration("filterTable", timer.getElapsedTime()); perfStat.logDuration("filterTable", timer.getElapsedTime());
timer.reset(); timer.reset();
timer.start(); timer.start();
updateTable(siteId, result, mode); updateTable(result, mode);
timer.stop(); timer.stop();
perfStat.logDuration("updateTable", timer.getElapsedTime()); perfStat.logDuration("updateTable", timer.getElapsedTime());
} finally { } finally {
@ -472,7 +477,7 @@ public class ActiveTable {
} }
if (etn != null) { if (etn != null) {
query.addQueryParam("etn", etn, "in"); query.addQueryParam("key.etn", etn, "in");
} }
if (requestValidTimes && (currentTime != null)) { if (requestValidTimes && (currentTime != null)) {
@ -491,7 +496,7 @@ public class ActiveTable {
query.setMaxResults(1); query.setMaxResults(1);
} }
query.addQueryParam("officeid", siteId, "in"); query.addQueryParam("key.officeid", siteId, "in");
List<ActiveTableRecord> result = null; List<ActiveTableRecord> result = null;
try { 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 * @param changes
* the updated table followed by the purged records * the updated table followed by the purged records
*/ */
private static void updateTable(String siteId, MergeResult changes, private static void updateTable(MergeResult changes, ActiveTableMode mode) {
ActiveTableMode mode) {
List<ActiveTableRecord> updated = changes.updatedList; List<ActiveTableRecord> updated = changes.updatedList;
List<ActiveTableRecord> purged = changes.purgedList; 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 CoreDao dao = (ActiveTableMode.OPERATIONAL.equals(mode)) ? operationalDao
: practiceDao; : 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) { if (result != null) {
updateTable(siteId, result, tableName); updateTable(result, tableName);
} }
} finally { } finally {
if (writeLock != null) { if (writeLock != null) {

View file

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

View file

@ -31,6 +31,7 @@
# __ne__(). # __ne__().
# 07/23/13 2212 dgilling Fix typo in __eq__(). # 07/23/13 2212 dgilling Fix typo in __eq__().
# 04/28/2015 4027 randerso Expunged Calendar from ActiveTableRecord # 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 raise KeyError
def __delitem__(self, key): def __delitem__(self, key):
# TODO: implement this
pass pass
def __deepcopy__(self, memo): def __deepcopy__(self, memo):

View file

@ -37,6 +37,7 @@
# 05/15/14 #3157 dgilling Support multiple TPC and SPC sites. # 05/15/14 #3157 dgilling Support multiple TPC and SPC sites.
# 03/04/2015 #4129 randerso Log the active table changes at info level # 03/04/2015 #4129 randerso Log the active table changes at info level
# in the active table change log # 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)) self.printActiveTable(ignoredOldReplaceAct, 1))
atChangeLog.info("Table Changes: " + str(changes)) atChangeLog.info("Table Changes: " + str(changes))
purges.extend(oldReplaceEntriesAct)
purges.extend(oldReplaceEntriesPast)
return activeTable, purges, changes return activeTable, purges, changes
def getMergeResults(self): def getMergeResults(self):