rm edexOsgi/com.raytheon.uf.edex.dissemination
This commit is contained in:
parent
83af442096
commit
20cb5cebc8
20 changed files with 0 additions and 2111 deletions
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
|
@ -1,34 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.raytheon.uf.edex.dissemination</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.python.pydev.PyDevBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.python.pydev.pythonNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?eclipse-pydev version="1.0"?>
|
||||
|
||||
<pydev_project>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.5</pydev_property>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
|
||||
</pydev_project>
|
|
@ -1,30 +0,0 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Dissemination Plug-in
|
||||
Bundle-SymbolicName: com.raytheon.uf.edex.dissemination
|
||||
Bundle-Version: 1.16.0.qualifier
|
||||
Bundle-Vendor: RAYTHEON
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Import-Package: com.raytheon.edex.exception,
|
||||
com.raytheon.uf.common.dataplugin.text,
|
||||
com.raytheon.uf.common.dataplugin.text.db,
|
||||
com.raytheon.uf.common.dissemination,
|
||||
com.raytheon.uf.common.localization,
|
||||
com.raytheon.uf.common.localization.exception,
|
||||
com.raytheon.uf.common.python,
|
||||
com.raytheon.uf.common.serialization,
|
||||
com.raytheon.uf.common.serialization.comm,
|
||||
com.raytheon.uf.common.status,
|
||||
com.raytheon.uf.edex.core,
|
||||
com.raytheon.uf.edex.database,
|
||||
com.raytheon.uf.edex.database.purge,
|
||||
org.apache.camel
|
||||
Require-Bundle: org.jep;bundle-version="1.0.0",
|
||||
com.raytheon.uf.edex.plugin.text,
|
||||
com.raytheon.uf.common.site,
|
||||
org.springframework;bundle-version="2.5.6",
|
||||
com.raytheon.uf.edex.database,
|
||||
com.raytheon.uf.common.auth,
|
||||
com.raytheon.uf.edex.auth,
|
||||
com.raytheon.uf.edex.ndm
|
|
@ -1,6 +0,0 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
utility/,\
|
||||
.,\
|
||||
res/
|
|
@ -1,13 +0,0 @@
|
|||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<bean id="disseminationListener" class="com.raytheon.uf.edex.dissemination.ingest.DisseminationNationalDatasetSubscriber" />
|
||||
|
||||
<bean factory-bean="ndmProc" factory-method="registerListener">
|
||||
<constructor-arg value="awipsPriorities.txt" />
|
||||
<constructor-arg ref="disseminationListener" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
|
@ -1,50 +0,0 @@
|
|||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://camel.apache.org/schema/spring
|
||||
http://camel.apache.org/schema/spring/camel-spring.xsd">
|
||||
|
||||
<bean id="oupAckMgr" class="com.raytheon.uf.edex.dissemination.OUPAckManager" />
|
||||
<bean id="oupHandler" class="com.raytheon.uf.edex.dissemination.OUPHandler">
|
||||
<property name="ackManager" ref="oupAckMgr" />
|
||||
</bean>
|
||||
<bean id="oupTestHandler" class="com.raytheon.uf.edex.dissemination.OUPTestHandler">
|
||||
<property name="oupHandler" ref="oupHandler" />
|
||||
</bean>
|
||||
|
||||
<camelContext id="handleoupAckMgrContext" xmlns="http://camel.apache.org/schema/spring"
|
||||
errorHandlerRef="errorHandler">
|
||||
<!-- Non clustered, specifically used by handleOUP.py to push published
|
||||
files directly into stream -->
|
||||
<!-- This route does not delete the file passed! If delete is needed, create
|
||||
a new route and use moveFileToArchive -->
|
||||
<route id="handleoupFilePush">
|
||||
<from
|
||||
uri="jms-durable:queue:Ingest.handleoup"/>
|
||||
<doTry>
|
||||
<bean ref="stringToFile" />
|
||||
<bean ref="manualProc" />
|
||||
<to
|
||||
uri="jms-durable:queue:handleoup.dropbox"/>
|
||||
<doCatch>
|
||||
<exception>java.lang.Throwable</exception>
|
||||
<to
|
||||
uri="log:oup?level=ERROR&showBody=true" />
|
||||
</doCatch>
|
||||
</doTry>
|
||||
</route>
|
||||
|
||||
<route id="oupAckMGrRoute">
|
||||
<from uri="jms-generic:topic:mhs.ackmgr" />
|
||||
<doTry>
|
||||
<bean ref="oupAckMgr" method="processAck" />
|
||||
<doCatch>
|
||||
<exception>java.lang.Throwable</exception>
|
||||
<to uri="log:oup?level=INFO"/>
|
||||
</doCatch>
|
||||
</doTry>
|
||||
</route>
|
||||
</camelContext>
|
||||
|
||||
</beans>
|
|
@ -1,239 +0,0 @@
|
|||
/**
|
||||
* 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.edex.dissemination;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.text.db.AfosToAwips;
|
||||
import com.raytheon.uf.common.dissemination.OUPRequest;
|
||||
import com.raytheon.uf.common.dissemination.OfficialUserProduct;
|
||||
import com.raytheon.uf.edex.database.DataAccessLayerException;
|
||||
import com.raytheon.uf.edex.dissemination.transmitted.TransProdHeader;
|
||||
import com.raytheon.uf.edex.dissemination.transmitted.TransmittedProductList;
|
||||
import com.raytheon.uf.edex.plugin.text.AfosToAwipsLookup;
|
||||
|
||||
/**
|
||||
* Utilities for generating a wmo header or tracking headers
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ------------ --------------------
|
||||
* Nov 13, 2009 njensen Initial creation
|
||||
* Aug 20, 2012 15340 D. Friedman Fix BBB problems
|
||||
* Aug 09, 2016 5801 tgurney Use AfosToAwipsLookup
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
*/
|
||||
|
||||
public class ModifyProduct {
|
||||
|
||||
private static final SimpleDateFormat DDHHMM = new SimpleDateFormat(
|
||||
"ddHHmm");
|
||||
|
||||
public static TransProdHeader getProductHeader(OfficialUserProduct product)
|
||||
throws OUPHeaderException {
|
||||
TransProdHeader header = null;
|
||||
String[] splitLines = product.getProductText().split("\n");
|
||||
String[] firstLine = splitLines[0].split(" ");
|
||||
if (firstLine.length < 3) {
|
||||
throw new OUPHeaderException("Bad wmo header on product: "
|
||||
+ splitLines[0]);
|
||||
}
|
||||
String ttaaii = firstLine[0];
|
||||
String cccc = firstLine[1];
|
||||
String productTime = firstLine[2];
|
||||
String productAwipsId = product.getAwipsWanPil().substring(4);
|
||||
List<AfosToAwips> list = AfosToAwipsLookup.lookupAfosId(ttaaii, cccc)
|
||||
.getIdList();
|
||||
String productId = null;
|
||||
for (AfosToAwips ata : list) {
|
||||
String afosId = ata.getAfosid();
|
||||
String awipsId = afosId.substring(3);
|
||||
if (awipsId.equals(productAwipsId)) {
|
||||
productId = afosId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (productId != null) {
|
||||
String wmoId = ttaaii + " " + cccc;
|
||||
String bbbid = product.getWmoType();
|
||||
header = new TransProdHeader(productId, wmoId, productTime, bbbid);
|
||||
} else {
|
||||
throw new OUPHeaderException(
|
||||
"Error determining afosID. No matching afosID found for ttaaii "
|
||||
+ ttaaii + " cccc " + cccc + " afosID %"
|
||||
+ productAwipsId);
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
public static OUPRequest addWmoHeader(OUPRequest req)
|
||||
throws OUPHeaderException {
|
||||
String text = req.getProduct().getProductText();
|
||||
String awipsWanPil = req.getProduct().getAwipsWanPil();
|
||||
String cccc = awipsWanPil.substring(0, 4);
|
||||
String nnn = awipsWanPil.substring(4, 7);
|
||||
String xxx = null;
|
||||
if (awipsWanPil.length() >= 10) {
|
||||
xxx = awipsWanPil.substring(7, 10);
|
||||
} else {
|
||||
xxx = awipsWanPil.substring(7);
|
||||
}
|
||||
|
||||
List<AfosToAwips> list = AfosToAwipsLookup.lookupAfosId(cccc, nnn,
|
||||
xxx.trim()).getIdList();
|
||||
if (list.size() == 1) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(list.get(0).getWmottaaii());
|
||||
sb.append(" ");
|
||||
sb.append(list.get(0).getWmocccc());
|
||||
sb.append(" ");
|
||||
if (req.getProduct().getUserDateTimeStamp() != null) {
|
||||
sb.append(req.getProduct().getUserDateTimeStamp());
|
||||
} else {
|
||||
synchronized (DDHHMM) {
|
||||
sb.append(DDHHMM.format(new Date()));
|
||||
}
|
||||
}
|
||||
if (req.getProduct().getWmoType() != null
|
||||
&& req.getProduct().getWmoType().length() > 0) {
|
||||
sb.append(" ");
|
||||
sb.append(req.getProduct().getWmoType());
|
||||
}
|
||||
sb.append("\n");
|
||||
sb.append(nnn);
|
||||
sb.append(xxx);
|
||||
sb.append("\n");
|
||||
sb.append(text);
|
||||
|
||||
req.getProduct().setProductText(sb.toString());
|
||||
req.getProduct().setNeedsWmoHeader(false);
|
||||
|
||||
return req;
|
||||
} else if (list.size() == 0) {
|
||||
throw new OUPHeaderException(
|
||||
"Error building WMO header. No matching ttaaii found for cccc "
|
||||
+ cccc + " nnn " + nnn + " xxx " + xxx);
|
||||
} else {
|
||||
throw new OUPHeaderException(
|
||||
"Error building WMO header. Too many matching ttaaii found for cccc "
|
||||
+ cccc + " nnn " + nnn + " xxx " + xxx);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean checkBBBField(OfficialUserProduct product,
|
||||
TransProdHeader header) throws DataAccessLayerException {
|
||||
boolean changed = false;
|
||||
String productBBB = header.getBbb();
|
||||
String[] splitLines = product.getProductText().split("\n", 2);
|
||||
String bbbToUse = TransmittedProductList.getBBB(header.getProductId(),
|
||||
header.getWmoId(), header.getProductTime(), header.getBbb());
|
||||
|
||||
if (!productBBB.equals(bbbToUse)) {
|
||||
productBBB = bbbToUse;
|
||||
}
|
||||
|
||||
if (productBBB != null) {
|
||||
// if the BBB is already in the wmo header do not append
|
||||
if (!splitLines[0].endsWith(" " + productBBB)) {
|
||||
splitLines[0] += " " + productBBB;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean first = true;
|
||||
for (String line : splitLines) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
sb.append("\n");
|
||||
}
|
||||
sb.append(line);
|
||||
}
|
||||
product.setProductText(sb.toString());
|
||||
changed = true;
|
||||
}
|
||||
header.setBbb(productBBB);
|
||||
}
|
||||
product.setWmoType(productBBB);
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
public static String convertNewline2rrn(String textString) {
|
||||
StringBuffer newString = new StringBuffer();
|
||||
|
||||
// Don't do any change if string doesn't contain any newline
|
||||
if (textString.contains("\n") == false) {
|
||||
return textString;
|
||||
}
|
||||
|
||||
String[] lines = textString.split("\n");
|
||||
|
||||
for (String line : lines) {
|
||||
int length = line.length();
|
||||
|
||||
// The index of the first "\n" is bigger than 1
|
||||
if (length > 1) {
|
||||
|
||||
// "...xx\n" case
|
||||
if (line.charAt(length - 1) != '\r') {
|
||||
// replace with "...xx\r\r\n"
|
||||
newString.append(line.substring(0, length));
|
||||
newString.append("\r\r\n");
|
||||
|
||||
// "...x\r\n" and case
|
||||
} else if (line.charAt(length - 2) != '\r') {
|
||||
// replace with ""...x\r\r\n"
|
||||
newString.append(line.substring(0, length - 1));
|
||||
newString.append("\r\r\n");
|
||||
|
||||
// "...\r\r\n" case
|
||||
} else {
|
||||
// jusy copy "..."
|
||||
newString.append(line);
|
||||
}
|
||||
|
||||
// "\r\n" and "x\n" case
|
||||
} else if (length == 1) {
|
||||
char char0 = line.charAt(0);
|
||||
|
||||
// copy the "x" if is the "x\n" case
|
||||
if (char0 != '\r') {
|
||||
newString.append(char0);
|
||||
}
|
||||
|
||||
newString.append("\r\r\n");
|
||||
|
||||
// "\n" case
|
||||
} else {
|
||||
newString.append("\r\r\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return newString.toString();
|
||||
}
|
||||
}
|
|
@ -1,189 +0,0 @@
|
|||
package com.raytheon.uf.edex.dissemination;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.camel.Header;
|
||||
|
||||
import com.raytheon.uf.common.dissemination.OUPResponse;
|
||||
|
||||
/**
|
||||
* Manages MHS acknowledgments. Currently this means supporting synchronous
|
||||
* waiting for acknowledgments.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 2012-04-13 DR 10388 D. Friedman Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
|
||||
public class OUPAckManager {
|
||||
|
||||
private static final long MAX_ENTRY_LIFE_TIME_MILLIS = 15 * 60 * 1000; // 15 minutes
|
||||
private static final long ACK_WAIT_TIMEOUT_MILLIS = 5 * 60 * 1000; // 5 minutes
|
||||
|
||||
private static final String ACK_RESPONSE = "ACK";
|
||||
private static final String NACK_RESPONSE = "NACK";
|
||||
private static final String NWWS_UPLINK_ADDRESS = "NWWSUP";
|
||||
private static final String[] EXCLUSIVE_ADDRESS_SEARCH_STRINGS = { "NCF", "SBN" };
|
||||
|
||||
/*
|
||||
* EDEX can receive an ACK before waitAck is called. Because the ACK cannot
|
||||
* be correctly processed before the addresses are know (i.e., waitAck is
|
||||
* called), we must queue all ACKs for processing on the thread that calls
|
||||
* waitAck. This includes ACKs for messages that were not even sent from
|
||||
* this JVM. If OUP requests and ACK/NACK messages could be processed
|
||||
* serially in the same thread, this complexity could be reduced.
|
||||
*/
|
||||
private static class Entry {
|
||||
public Entry() {
|
||||
this.createTime = System.currentTimeMillis();
|
||||
}
|
||||
long createTime;
|
||||
String addresses;
|
||||
String result;
|
||||
ArrayList<Response> pendingResponses = new ArrayList<OUPAckManager.Response>(1);
|
||||
|
||||
boolean isDone() {
|
||||
if (result != null)
|
||||
return true;
|
||||
while (pendingResponses.size() > 0) {
|
||||
Response r = pendingResponses.remove(0);
|
||||
if (matches(r)) {
|
||||
result = r.response != null ? r.response : "(null response)";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Logic and comments from MhsWfoProduct.C: MhsWfoProduct::matches() */
|
||||
private boolean matches(Response r) {
|
||||
// Check for acks from the NWWS address.
|
||||
if (NWWS_UPLINK_ADDRESS.equals(r.sender)
|
||||
&& this.addresses.indexOf(NWWS_UPLINK_ADDRESS) >= 0)
|
||||
return true;
|
||||
|
||||
/*
|
||||
* If the message was sent to the NCF, then only handle acks from
|
||||
* the NCF. If the message was sent to the NCF for distribution on
|
||||
* the SBN, then only handle acks with the SBN address.
|
||||
*/
|
||||
for (String searchString : EXCLUSIVE_ADDRESS_SEARCH_STRINGS)
|
||||
if (this.addresses.indexOf(searchString) >= 0) {
|
||||
if (r.sender != null && r.sender.indexOf(searchString) >= 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* If none of the above special addresses were used, compare the
|
||||
* sender to the list of addresses. If there's only one address, and
|
||||
* the sender matches it, return true.
|
||||
*/
|
||||
if (addresses != null && addresses.equals(r.sender))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static class Response {
|
||||
private String sender;
|
||||
private String response;
|
||||
public Response(String sender, String response) {
|
||||
this.sender = sender;
|
||||
this.response = response;
|
||||
}
|
||||
}
|
||||
|
||||
private HashMap<String, Entry> entries = new HashMap<String, OUPAckManager.Entry>();
|
||||
|
||||
public Entry getEntry(String messageId) {
|
||||
synchronized (entries) {
|
||||
// Purge abandonded entries
|
||||
long purgeTime = System.currentTimeMillis() - MAX_ENTRY_LIFE_TIME_MILLIS;
|
||||
Iterator<Entry> i = entries.values().iterator();
|
||||
while (i.hasNext()) {
|
||||
Entry entry = i.next();
|
||||
if (entry.createTime <= purgeTime) {
|
||||
i.remove();
|
||||
synchronized (entry) {
|
||||
entry.result = "ACK wait purged";
|
||||
entry.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Entry entry = entries.get(messageId);
|
||||
if (entry == null) {
|
||||
entry = new Entry();
|
||||
entries.put(messageId, entry);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
/** Synchronously waits for an acknowledgment of the specified MHS message
|
||||
* @param messageId MHS message ID
|
||||
* @param addresses list of addresses used to determine which ACKs are relevant
|
||||
* @param response On return, the {@code acknowledged} and (if no positive ACK) {@code message}
|
||||
* properties will be set.
|
||||
* @param messageDescription description of the MHS message to be used in error messages
|
||||
*/
|
||||
public void waitAck(String messageId, String addresses, OUPResponse response, String messageDescription) {
|
||||
long now = System.currentTimeMillis();
|
||||
long targetTime = now + ACK_WAIT_TIMEOUT_MILLIS;
|
||||
Entry entry = getEntry(messageId);
|
||||
|
||||
synchronized (entry) {
|
||||
entry.addresses = addresses;
|
||||
while (! entry.isDone()) {
|
||||
now = System.currentTimeMillis();
|
||||
if (now < targetTime) {
|
||||
try {
|
||||
entry.wait(targetTime - now);
|
||||
} catch (InterruptedException e) {
|
||||
response.setAcknowledged(false);
|
||||
response.setMessage(String.format("Interrupted while waiting for acknowledgement of %s",
|
||||
messageDescription));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
response.setAcknowledged(false);
|
||||
response.setMessage(String.format("Timed out waiting for acknowledgement of %s",
|
||||
messageDescription));
|
||||
return;
|
||||
}
|
||||
}
|
||||
response.setAcknowledged(ACK_RESPONSE.equals(entry.result));
|
||||
if (! response.isAcknowledged())
|
||||
response.setMessage(String.format(
|
||||
"An error was received while sending %s to the WAN.\nA %s.",
|
||||
messageDescription,
|
||||
NACK_RESPONSE.equals(entry.result) ?
|
||||
"negative acknowledgment was received from the remote site" :
|
||||
"unknown response was received: " + entry.result));
|
||||
}
|
||||
|
||||
synchronized (this) {
|
||||
entries.remove(messageId);
|
||||
}
|
||||
}
|
||||
|
||||
public void processAck(String messageId, @Header("sender") String sender,
|
||||
@Header("response") String response) {
|
||||
Entry entry = getEntry(messageId);
|
||||
synchronized (entry) {
|
||||
entry.pendingResponses.add(new Response(sender, response));
|
||||
entry.notify();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,225 +0,0 @@
|
|||
/**
|
||||
* 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.edex.dissemination;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.raytheon.uf.common.auth.exception.AuthorizationException;
|
||||
import com.raytheon.uf.common.dataplugin.text.db.MixedCaseProductSupport;
|
||||
import com.raytheon.uf.common.dissemination.OUPRequest;
|
||||
import com.raytheon.uf.common.dissemination.OUPResponse;
|
||||
import com.raytheon.uf.common.dissemination.OfficialUserProduct;
|
||||
import com.raytheon.uf.common.localization.IPathManager;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
|
||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
||||
import com.raytheon.uf.common.python.PyUtil;
|
||||
import com.raytheon.uf.common.python.PythonScript;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.edex.auth.AuthManagerFactory;
|
||||
import com.raytheon.uf.edex.auth.IPermissionsManager;
|
||||
import com.raytheon.uf.edex.auth.req.AbstractPrivilegedRequestHandler;
|
||||
import com.raytheon.uf.edex.auth.resp.AuthorizationResponse;
|
||||
import com.raytheon.uf.edex.dissemination.transmitted.TransProdHeader;
|
||||
|
||||
import jep.JepException;
|
||||
|
||||
/**
|
||||
* IRequestHandler for OUPRequests
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ------------ -----------------------------------------
|
||||
* Oct 22, 2009 njensen Initial creation
|
||||
* Oct 12, 2012 15418 D. Friedman Use clustered TransmittedProductList
|
||||
* Jun 07, 2013 1981 mpduff This is now a privileged request handler.
|
||||
* Nov 20, 2013 16777 D. Friedman Add a test mode.
|
||||
* May 28, 2014 3211 njensen Use IAuthorizer instead of IRoleStorage
|
||||
* Feb 24, 2016 5411 randerso Force product to upper case if necessary
|
||||
* Aug 01, 2016 5744 mapeters Python script moved from edex_static to
|
||||
* common_static
|
||||
* Jul 17, 2017 6288 randerso Changed to use new Roles/Permissions
|
||||
* framework
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
*/
|
||||
|
||||
public class OUPHandler extends AbstractPrivilegedRequestHandler<OUPRequest> {
|
||||
private static final IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(OUPHandler.class);
|
||||
|
||||
private OUPAckManager ackManager;
|
||||
|
||||
@Override
|
||||
public OUPResponse handleRequest(OUPRequest request) throws Exception {
|
||||
return handleOUPRequest(request, false);
|
||||
}
|
||||
|
||||
public OUPResponse handleOUPRequest(OUPRequest request, boolean test)
|
||||
throws Exception {
|
||||
OfficialUserProduct oup = request.getProduct();
|
||||
OUPResponse resp = new OUPResponse();
|
||||
boolean changedBbb = false;
|
||||
if (oupOk(oup)) {
|
||||
try {
|
||||
if (oup.isNeedsWmoHeader()) {
|
||||
request = ModifyProduct.addWmoHeader(request);
|
||||
}
|
||||
TransProdHeader header = ModifyProduct.getProductHeader(oup);
|
||||
if (request.isCheckBBB() && !test) {
|
||||
changedBbb = ModifyProduct.checkBBBField(oup, header);
|
||||
if (changedBbb) {
|
||||
resp.setChangedBBB(request.getProduct().getWmoType());
|
||||
}
|
||||
}
|
||||
|
||||
String convertedProductText = ModifyProduct
|
||||
.convertNewline2rrn(oup.getProductText());
|
||||
|
||||
/*
|
||||
* Force to upper case if product is not enabled for mixed case
|
||||
* transmission
|
||||
*/
|
||||
String nnn = oup.getAwipsWanPil().substring(4, 7);
|
||||
convertedProductText = MixedCaseProductSupport
|
||||
.conditionalToUpper(nnn, convertedProductText);
|
||||
|
||||
oup.setProductText(convertedProductText);
|
||||
|
||||
PythonScript py = null;
|
||||
try {
|
||||
py = initializePython();
|
||||
Map<String, Object> args = new HashMap<>(1);
|
||||
args.put("oup", oup);
|
||||
args.put("afosID", header.getProductId());
|
||||
args.put("resp", resp);
|
||||
args.put("ackMgr", ackManager);
|
||||
args.put("test", test);
|
||||
resp.setAttempted(true);
|
||||
py.execute("process", args);
|
||||
} catch (JepException e) {
|
||||
resp.setMessage("Error executing handleOUP python");
|
||||
statusHandler.handle(Priority.SIGNIFICANT,
|
||||
"Error executing handleOUP python", e);
|
||||
} finally {
|
||||
if (py != null) {
|
||||
py.dispose();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* TODO: Should be updating TransmittedProductList here, after
|
||||
* success has been confirmed.
|
||||
*/
|
||||
} catch (OUPHeaderException e) {
|
||||
statusHandler.error(e.getMessage(), e);
|
||||
resp.setAttempted(false);
|
||||
resp.setMessage(
|
||||
"Product not sent, error encountered with header.\n"
|
||||
+ e.getMessage());
|
||||
}
|
||||
} else {
|
||||
resp.setAttempted(false);
|
||||
resp.setMessage(
|
||||
"Product not sent. OfficialUserProduct requires an awipsWanPil, "
|
||||
+ "product text, and product filename.");
|
||||
}
|
||||
|
||||
if ((resp != null) && (resp.getMessage() == null)) {
|
||||
resp.setMessage("");
|
||||
}
|
||||
return resp;
|
||||
}
|
||||
|
||||
private static boolean oupOk(OfficialUserProduct oup) {
|
||||
boolean ok = false;
|
||||
if (oup != null) {
|
||||
if ((oup.getAwipsWanPil() != null) && (oup.getFilename() != null)
|
||||
&& (oup.getProductText() != null)) {
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
private static PythonScript initializePython() {
|
||||
PythonScript python = null;
|
||||
IPathManager pathMgr = PathManagerFactory.getPathManager();
|
||||
LocalizationContext commonBase = pathMgr.getContext(
|
||||
LocalizationType.COMMON_STATIC, LocalizationLevel.BASE);
|
||||
|
||||
String path = pathMgr.getFile(commonBase,
|
||||
"dissemination" + IPathManager.SEPARATOR + "handleOUP.py")
|
||||
.getPath();
|
||||
String statusPath = pathMgr.getFile(commonBase, "python").getPath();
|
||||
try {
|
||||
python = new PythonScript(path,
|
||||
PyUtil.buildJepIncludePath(statusPath),
|
||||
OUPHandler.class.getClassLoader());
|
||||
} catch (JepException e) {
|
||||
statusHandler.handle(Priority.SIGNIFICANT,
|
||||
"Error initializing handleOUP python", e);
|
||||
}
|
||||
return python;
|
||||
}
|
||||
|
||||
public OUPAckManager getAckManager() {
|
||||
return ackManager;
|
||||
}
|
||||
|
||||
public void setAckManager(OUPAckManager ackManager) {
|
||||
this.ackManager = ackManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public AuthorizationResponse authorized(OUPRequest request)
|
||||
throws AuthorizationException {
|
||||
boolean authorized = false;
|
||||
|
||||
if (request.getUser().uniqueId().toString()
|
||||
.equals(OUPRequest.EDEX_ORIGINATION)) {
|
||||
authorized = true;
|
||||
} else {
|
||||
IPermissionsManager manager = AuthManagerFactory.getInstance()
|
||||
.getPermissionsManager();
|
||||
|
||||
authorized = manager.isPermitted(request.getRoleId());
|
||||
}
|
||||
|
||||
if (authorized) {
|
||||
return new AuthorizationResponse(authorized);
|
||||
} else {
|
||||
return new AuthorizationResponse(
|
||||
(request).getNotAuthorizedMessage());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/**
|
||||
* 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.edex.dissemination;
|
||||
|
||||
import com.raytheon.uf.edex.core.EdexException;
|
||||
|
||||
/**
|
||||
* Exception when dealing with the WMO header of Official User Products
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jan 5, 2010 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class OUPHeaderException extends EdexException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public OUPHeaderException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public OUPHeaderException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
package com.raytheon.uf.edex.dissemination;
|
||||
|
||||
import com.raytheon.uf.common.auth.exception.AuthorizationException;
|
||||
import com.raytheon.uf.common.dissemination.OUPTestRequest;
|
||||
import com.raytheon.uf.edex.auth.req.AbstractPrivilegedRequestHandler;
|
||||
import com.raytheon.uf.edex.auth.resp.AuthorizationResponse;
|
||||
|
||||
/**
|
||||
* Check if an OUPRequest will work
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ------------ -----------------------------------------
|
||||
* Nov 20, 2013 16777 D. Friedman Initial creation
|
||||
* Jul 18, 2017 6288 randerso Changed to use new Roles/Permissions
|
||||
* framework
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
public class OUPTestHandler
|
||||
extends AbstractPrivilegedRequestHandler<OUPTestRequest> {
|
||||
|
||||
private OUPHandler oupHandler;
|
||||
|
||||
@Override
|
||||
public Object handleRequest(OUPTestRequest request) throws Exception {
|
||||
return oupHandler.handleOUPRequest(request.getOupRequest(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthorizationResponse authorized(OUPTestRequest request)
|
||||
throws AuthorizationException {
|
||||
return oupHandler.authorized(request.getOupRequest());
|
||||
}
|
||||
|
||||
public OUPHandler getOupHandler() {
|
||||
return oupHandler;
|
||||
}
|
||||
|
||||
public void setOupHandler(OUPHandler oupHandler) {
|
||||
this.oupHandler = oupHandler;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/**
|
||||
* 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.edex.dissemination;
|
||||
|
||||
/**
|
||||
* StatusConstants for dissemination
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Oct 29, 2009 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class StatusConstants {
|
||||
|
||||
public static final String PLUGIN_NAME = "com.raytheon.uf.edex.dissemination";
|
||||
|
||||
public static final String CATEGORY_HANDLE_OUP = "HandleOUP";
|
||||
|
||||
}
|
|
@ -1,151 +0,0 @@
|
|||
/**
|
||||
* 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.edex.dissemination.ingest;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import com.raytheon.uf.common.localization.ILocalizationFile;
|
||||
import com.raytheon.uf.common.localization.IPathManager;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
|
||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
||||
import com.raytheon.uf.common.localization.SaveableOutputStream;
|
||||
import com.raytheon.uf.common.localization.exception.LocalizationException;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.edex.ndm.ingest.INationalDatasetSubscriber;
|
||||
|
||||
/**
|
||||
* Dissemination NDM subscriber.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------------------------
|
||||
* Jan 13, 2011 bfarmer Initial creation
|
||||
* Mar 06, 2014 2876 mpduff New NDM plugin.
|
||||
* Aug 01, 2016 5744 mapeters Save priorities file to
|
||||
* common_static.configured instead of
|
||||
* edex_static.base, use ILocalizationFile
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bfarmer
|
||||
*/
|
||||
|
||||
public class DisseminationNationalDatasetSubscriber implements
|
||||
INationalDatasetSubscriber {
|
||||
private static final IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(DisseminationNationalDatasetSubscriber.class);
|
||||
|
||||
private static final String AWIPS_PRIORITIES_FILENAME = "dissemination"
|
||||
+ IPathManager.SEPARATOR + "awipsPriorities.txt";
|
||||
|
||||
@Override
|
||||
public void notify(String fileName, File file) {
|
||||
if ("awipsPriorities.txt".equals(fileName)) {
|
||||
IPathManager pathMgr = PathManagerFactory.getPathManager();
|
||||
LocalizationContext lc = pathMgr.getContext(
|
||||
LocalizationType.COMMON_STATIC,
|
||||
LocalizationLevel.CONFIGURED);
|
||||
ILocalizationFile outFile = pathMgr.getLocalizationFile(lc,
|
||||
AWIPS_PRIORITIES_FILENAME);
|
||||
long time = System.currentTimeMillis();
|
||||
String backupFilename = "dissemination" + IPathManager.SEPARATOR
|
||||
+ "awipsPriorities" + time + ".txt";
|
||||
ILocalizationFile backupFile = pathMgr.getLocalizationFile(lc,
|
||||
backupFilename);
|
||||
|
||||
saveFile(outFile, backupFile);
|
||||
saveFile(file, outFile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the contents of inFile to outFile and save it to the localization
|
||||
* server
|
||||
*
|
||||
* @param inFile
|
||||
* @param outFile
|
||||
*/
|
||||
private void saveFile(ILocalizationFile inFile, ILocalizationFile outFile) {
|
||||
if (inFile != null && inFile.exists()) {
|
||||
try (InputStream is = inFile.openInputStream();
|
||||
SaveableOutputStream os = outFile.openOutputStream()) {
|
||||
saveInputStreamToLocalization(is, os);
|
||||
} catch (IOException | LocalizationException e) {
|
||||
String msg = "Failed to save " + inFile.getPath() + " to "
|
||||
+ outFile.getPath();
|
||||
statusHandler.handle(Priority.PROBLEM, msg, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the contents inFile to outFile and save it to the localization
|
||||
* server
|
||||
*
|
||||
* @param inFile
|
||||
* @param outFile
|
||||
*/
|
||||
private void saveFile(File inFile, ILocalizationFile outFile) {
|
||||
if (inFile != null && inFile.exists()) {
|
||||
try (FileInputStream is = new FileInputStream(inFile);
|
||||
SaveableOutputStream os = outFile.openOutputStream()) {
|
||||
saveInputStreamToLocalization(is, os);
|
||||
} catch (IOException e) {
|
||||
String msg = "Failed to save " + inFile.getAbsolutePath()
|
||||
+ " to localization file " + outFile.getPath();
|
||||
statusHandler.handle(Priority.PROBLEM, msg, e);
|
||||
} catch (LocalizationException e) {
|
||||
String msg = "Failed to open output stream for file: "
|
||||
+ outFile.getPath();
|
||||
statusHandler.handle(Priority.PROBLEM, msg, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the contents of the given InputStream to the SaveableOutputStream
|
||||
* and save it to the localization server
|
||||
*
|
||||
* @param is
|
||||
* @param os
|
||||
* @throws IOException
|
||||
*/
|
||||
private void saveInputStreamToLocalization(InputStream is,
|
||||
SaveableOutputStream os) throws IOException {
|
||||
byte[] buf = new byte[2048];
|
||||
int len = is.read(buf);
|
||||
while (len > 0) {
|
||||
os.write(buf, 0, len);
|
||||
len = is.read(buf);
|
||||
}
|
||||
|
||||
os.save();
|
||||
}
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
/**
|
||||
* 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.edex.dissemination.transmitted;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Nov 10, 2009 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class TransProdHeader {
|
||||
|
||||
private String productId;
|
||||
|
||||
private String wmoId;
|
||||
|
||||
private String productTime;
|
||||
|
||||
private String bbb;
|
||||
|
||||
public TransProdHeader(String productId, String wmoId, String productTime,
|
||||
String bbb) {
|
||||
this.productId = productId;
|
||||
this.wmoId = wmoId;
|
||||
this.productTime = productTime;
|
||||
this.bbb = bbb;
|
||||
if (this.bbb == null) {
|
||||
this.bbb = "";
|
||||
}
|
||||
}
|
||||
|
||||
public boolean matches(String productId, String wmoId) {
|
||||
return (this.productId.equals(productId) && this.wmoId.equals(wmoId));
|
||||
}
|
||||
|
||||
public String getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
public void setProductId(String productId) {
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
public String getWmoId() {
|
||||
return wmoId;
|
||||
}
|
||||
|
||||
public void setWmoId(String wmoId) {
|
||||
this.wmoId = wmoId;
|
||||
}
|
||||
|
||||
public String getProductTime() {
|
||||
return productTime;
|
||||
}
|
||||
|
||||
public void setProductTime(String productTime) {
|
||||
this.productTime = productTime;
|
||||
}
|
||||
|
||||
public String getBbb() {
|
||||
return bbb;
|
||||
}
|
||||
|
||||
public void setBbb(String bbb) {
|
||||
this.bbb = bbb;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,188 +0,0 @@
|
|||
/**
|
||||
* 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.edex.dissemination.transmitted;
|
||||
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.edex.database.cluster.ClusterLockUtils;
|
||||
import com.raytheon.uf.edex.database.cluster.ClusterLockUtils.LockState;
|
||||
import com.raytheon.uf.edex.database.cluster.ClusterTask;
|
||||
import com.raytheon.uf.edex.database.cluster.handler.CurrentTimeClusterLockHandler;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Nov 10, 2009 njensen Initial creation
|
||||
* 08/20/2012 DR 15340 D. Friedman Fix BBB problems
|
||||
* 10/12/2012 DR 15418 D. Friedman Make BBB determination cluster-aware
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class TransmittedProductList {
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus.getHandler(TransmittedProductList.class);
|
||||
|
||||
private static final String LOCK_NAME = "OUP-TransProdList";
|
||||
|
||||
/** Represents a BBB field that is set to an empty value (as opposed to
|
||||
* an "unknown" or "not set" state.
|
||||
*/
|
||||
private static final String EMPTY_BBB_VAL = "-";
|
||||
|
||||
private static final long CLUSTER_LOCK_TIMEOUT = 15 * 1000;
|
||||
|
||||
public static String getBBB(String productId, String wmoId,
|
||||
String productTime, String productBBB) {
|
||||
/* If the user has assigned a value to the BBB field, just pass the
|
||||
* product through without incrementing the BBB value. If that
|
||||
* assigned value is RRx, still need to need to update the
|
||||
* cluster-shared header list.
|
||||
*/
|
||||
boolean getNextBBB = true;
|
||||
if (productBBB.length() == 3) {
|
||||
String left2 = productBBB.substring(0, 2);
|
||||
if (left2.equals("RR"))
|
||||
getNextBBB = false;
|
||||
else if (left2.equals("AA") || left2.equals("CC"))
|
||||
return productBBB;
|
||||
}
|
||||
|
||||
String lockName = LOCK_NAME;
|
||||
CurrentTimeClusterLockHandler lockHandler = null;
|
||||
lockHandler = new CurrentTimeClusterLockHandler(CLUSTER_LOCK_TIMEOUT,
|
||||
false);
|
||||
ClusterTask ct = ClusterLockUtils.lock(lockName,
|
||||
wmoId, lockHandler, true);
|
||||
if (! ct.getLockState().equals(LockState.SUCCESSFUL))
|
||||
statusHandler.handle(Priority.ERROR,
|
||||
String.format("Unable to get cluster lock for %s %s. Proceeding without it.",
|
||||
wmoId, productId));
|
||||
try {
|
||||
TphInfo info = parse(ct.getExtraInfo());
|
||||
String result;
|
||||
if (getNextBBB) {
|
||||
String tplBBB = info.getBBBForTime(productTime);
|
||||
String bbbToUse = getNextBBB(productBBB, tplBBB);
|
||||
info.setBBBForTime(productTime, isSet(bbbToUse) ? bbbToUse : EMPTY_BBB_VAL);
|
||||
statusHandler.handle(isSet(bbbToUse) ? Priority.INFO : Priority.VERBOSE,
|
||||
String.format("For %s %s DDHHMM=%s,BBB=%s,tplBBB=%s, use BBB=%s",
|
||||
wmoId, productId, productTime, productBBB, tplBBB, bbbToUse));
|
||||
// Current protocol is to return null for empty case
|
||||
result = isSet(bbbToUse) ? bbbToUse : null;
|
||||
} else {
|
||||
statusHandler.handle(Priority.INFO,
|
||||
String.format("Product %s %s DDHHMM=%s explicity requested BBB=%s",
|
||||
wmoId, productId, productTime, productBBB));
|
||||
info.setBBBForTime(productTime, productBBB);
|
||||
result = productBBB;
|
||||
}
|
||||
lockHandler.setExtraInfo(info.format());
|
||||
return result;
|
||||
} finally {
|
||||
if (ct.getLockState().equals(LockState.SUCCESSFUL))
|
||||
ClusterLockUtils.unlock(ct, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static String getNextBBB(String productBBB, String transmittedBBB) {
|
||||
if (! isSet(transmittedBBB))
|
||||
return "";
|
||||
else if (EMPTY_BBB_VAL.equals(transmittedBBB))
|
||||
return "RRA";
|
||||
|
||||
char newX = transmittedBBB.charAt(2);
|
||||
if (newX == 'X') {
|
||||
newX = 'A';
|
||||
} else {
|
||||
newX++;
|
||||
}
|
||||
return transmittedBBB.substring(0, 2) + Character.toString(newX);
|
||||
}
|
||||
|
||||
public static boolean isSet(String s) {
|
||||
return s != null && s.length() > 0;
|
||||
}
|
||||
|
||||
/** Manages the storage of transmitted product header state in the
|
||||
* cluster lock table. Currently only supports tracking state for
|
||||
* one minute at a time (like AWIPS I.)
|
||||
*/
|
||||
private static class TphInfo {
|
||||
private String time;
|
||||
private String bbb;
|
||||
|
||||
public String format() {
|
||||
if (isSet(time))
|
||||
return String.format("%s:%s", time, isSet(bbb) ? bbb : "");
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
public void setBBBForTime(String productTime, String bbbToUse) {
|
||||
time = productTime;
|
||||
bbb = isSet(bbbToUse) ? bbbToUse : null;
|
||||
}
|
||||
|
||||
public String getBBBForTime(String productTime) {
|
||||
if (productTime != null && productTime.equals(time))
|
||||
return isSet(bbb) ? bbb : null;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static TphInfo parse(String input) {
|
||||
TphInfo inf = new TphInfo();
|
||||
if (input != null) {
|
||||
String[] parts = input.split(":");
|
||||
if (parts.length == 2) {
|
||||
inf.time = parts[0]; // Only compared via String.equals; no need to validate further
|
||||
if (validateBBB(parts[1]))
|
||||
inf.bbb = parts[1];
|
||||
}
|
||||
}
|
||||
return inf;
|
||||
}
|
||||
|
||||
private static boolean validateBBB(String bbb) {
|
||||
if (EMPTY_BBB_VAL.equals(bbb))
|
||||
return true;
|
||||
else if (bbb.length() == 3) {
|
||||
int i;
|
||||
for (i = 0; i < bbb.length(); ++i)
|
||||
if (bbb.charAt(i) < 'A' || bbb.charAt(i) > 'Z')
|
||||
break;
|
||||
if (i == bbb.length())
|
||||
return true;
|
||||
}
|
||||
statusHandler.handle(Priority.ERROR,
|
||||
String.format("Invalid BBB in cluster lock info: \"%s\"", bbb));
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
# -------------------------------------------------------------------------
|
||||
# awipsPriorities.txt
|
||||
#
|
||||
# Table containing AFOS product categories (NNN) and corresponding priorities.
|
||||
#
|
||||
# Column 1: AFOS product category
|
||||
# Column 2: AWIPS transmission priority which is different from AFOS
|
||||
# AFOS = 1 (hi) to 5 (low)
|
||||
# AWIPS = 2 (hi) to 0 (low)
|
||||
# Since the default is 0, only priority 1 and 2 are in this file
|
||||
# -------------------------------------------------------------------------
|
||||
ACR 1
|
||||
ADA 1
|
||||
ADX 1
|
||||
AIR 1
|
||||
ALT 2
|
||||
ARS 1
|
||||
AVA 1
|
||||
AVW 2
|
||||
AWG 2
|
||||
AWN 2
|
||||
AWU 1
|
||||
AWW 2
|
||||
BOT 1
|
||||
BOY 1
|
||||
CAE 1
|
||||
CDW 2
|
||||
CEM 2
|
||||
CFA 1
|
||||
CFS 1
|
||||
CFW 2
|
||||
CHG 2
|
||||
CWA 1
|
||||
EQW 2
|
||||
EVI 2
|
||||
EXM 1
|
||||
EXT 1
|
||||
FFA 2
|
||||
FFM 1
|
||||
FFS 2
|
||||
FFW 2
|
||||
FLS 2
|
||||
FLW 2
|
||||
FOB 1
|
||||
FRW 2
|
||||
FZL 1
|
||||
HLS 2
|
||||
HMW 2
|
||||
HSR 1
|
||||
IAO 1
|
||||
LAE 1
|
||||
LEW 2
|
||||
LSH 2
|
||||
LSR 2
|
||||
MAW 1
|
||||
MBK 2
|
||||
MTR 1
|
||||
NIM 2
|
||||
NPW 2
|
||||
NUW 2
|
||||
OPU 2
|
||||
OWA 1
|
||||
OWW 2
|
||||
PSH 2
|
||||
PWO 2
|
||||
RCM 1
|
||||
RFW 2
|
||||
RHW 2
|
||||
ROB 1
|
||||
SAB 2
|
||||
SAO 1
|
||||
SAW 2
|
||||
SCP 1
|
||||
SDO 1
|
||||
SEL 2
|
||||
SEV 2
|
||||
SIG 2
|
||||
SLS 2
|
||||
SMW 2
|
||||
SPF 2
|
||||
SPS 2
|
||||
SPW 2
|
||||
STA 2
|
||||
STW 2
|
||||
SVR 2
|
||||
SVS 2
|
||||
TAP 1
|
||||
TCD 2
|
||||
TCE 2
|
||||
TCM 2
|
||||
TCP 2
|
||||
TCU 2
|
||||
TDM 1
|
||||
TDT 1
|
||||
TMA 2
|
||||
TMM 1
|
||||
TMT 1
|
||||
TOE 1
|
||||
TOR 2
|
||||
TSM 1
|
||||
TSU 2
|
||||
VOW 2
|
||||
WA0 2
|
||||
WA1 2
|
||||
WA2 2
|
||||
WA3 2
|
||||
WA4 2
|
||||
WA5 2
|
||||
WA6 2
|
||||
WA7 2
|
||||
WA8 2
|
||||
WA9 2
|
||||
WAC 2
|
||||
WAR 2
|
||||
WAT 2
|
||||
WCM 2
|
||||
WCN 2
|
||||
WS1 2
|
||||
WS2 2
|
||||
WS3 2
|
||||
WS4 2
|
||||
WS5 2
|
||||
WS6 2
|
||||
WS7 2
|
||||
WS8 2
|
||||
WS9 2
|
||||
WST 2
|
||||
WSV 2
|
||||
WSW 2
|
||||
WVM 1
|
||||
WWA 2
|
|
@ -1,592 +0,0 @@
|
|||
##
|
||||
# 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.
|
||||
##
|
||||
|
||||
#
|
||||
# Derived from port of handleOUP.pl, but diverged to support single path
|
||||
# of dissemination. Assigns a priority to the product, and attempts to send
|
||||
# it to the message handling system if it's not in the include lists.
|
||||
#
|
||||
#
|
||||
# SOFTWARE HISTORY
|
||||
#
|
||||
# Date Ticket# Engineer Description
|
||||
# ------------ ---------- ----------- --------------------------
|
||||
# 10/28/09 njensen Initial Creation.
|
||||
# 12/09/09 DR3778 M. Huang Add acknowledgment handling
|
||||
# 09/05/11 DR9602 M. Huang Fix acknowledgment handling error
|
||||
# 04/13/12 DR 10388 D. Friedman Correct acknowledgment handling
|
||||
# 08/17/12 DR 15304 D. Friedman Use unique output file names
|
||||
# 10/12/12 DR 15418 D. Friedman Use unique attachment file names
|
||||
# 11/20/13 DR 16777 D. Friedman Add a test mode.
|
||||
# 12/05/16 DR 16842 D. Friedman Do not set product ID on MhsMessage
|
||||
# 07/29/14 DR 2914 G. Armendariz Remove call to PropertiesFactory
|
||||
# Apr 25, 2015 4952 njensen Updated for new JEP API
|
||||
# Oct 09, 2015 4790 dgilling Set msg_send code for NCF products
|
||||
# to 134.
|
||||
# Aug 01, 2016 5744 mapeters Config files moved from
|
||||
# edex_static to common_static,
|
||||
# get highest version of files
|
||||
# Dec 12, 2016 DR 19612 D. Friedman Fix identifier typos
|
||||
# Dec 14, 2016 DCS19530 jdynina Added sending of FTM products to RPG
|
||||
#
|
||||
#
|
||||
|
||||
##
|
||||
# This is a base file that is not intended to be overridden.
|
||||
##
|
||||
|
||||
|
||||
import time, os, os.path, sys, subprocess, select, errno
|
||||
import logging, UFStatusHandler
|
||||
from com.raytheon.uf.common.dissemination import OUPResponse
|
||||
_Logger = logging.getLogger("HandleOUP")
|
||||
_Logger.addHandler(UFStatusHandler.UFStatusHandler("com.raytheon.uf.edex.dissemination", "HandleOUP", level=logging.INFO))
|
||||
_Logger.setLevel(logging.INFO)
|
||||
|
||||
DB_SUCCESS = 0;
|
||||
DB_FAILURE = 1;
|
||||
DB_TIMEOUT = 2;
|
||||
DB_DUPLICATE = 4;
|
||||
|
||||
ACTION_CODES = {}
|
||||
from com.raytheon.uf.common.localization import PathManagerFactory
|
||||
from com.raytheon.uf.common.localization import LocalizationContext
|
||||
LocalizationType = LocalizationContext.LocalizationType
|
||||
LocalizationLevel = LocalizationContext.LocalizationLevel
|
||||
DISSEMINATION_DIR = 'dissemination/'
|
||||
pathMgr = PathManagerFactory.getPathManager()
|
||||
path = pathMgr.getStaticFile(DISSEMINATION_DIR + 'rcv_action2codes.txt').getPath()
|
||||
f = open(path)
|
||||
for line in f:
|
||||
codeSplit = line.split()
|
||||
ACTION_CODES[codeSplit[0]] = codeSplit[1]
|
||||
f.close()
|
||||
|
||||
from com.raytheon.uf.edex.core import EDEXUtil
|
||||
dataDir = EDEXUtil.getEdexData();
|
||||
OUT_DIR = dataDir + 'outgoing'
|
||||
if not os.path.isdir(OUT_DIR):
|
||||
os.mkdir(OUT_DIR)
|
||||
INGEST_DIR = dataDir + 'manual'
|
||||
INGEST_ROUTE = 'handleoupFilePush'
|
||||
SITE_ID = EDEXUtil.getEdexSite()
|
||||
|
||||
def process(oup, afosID, resp, ackMgr=None, test=False):
|
||||
_Logger.info("handleOUP.py received " + str(oup.getFilename()))
|
||||
wmoTypeString = ""
|
||||
userDateTimeStamp = ""
|
||||
msg = ''
|
||||
|
||||
# WMO message type, aka bbb
|
||||
if oup.getWmoType():
|
||||
wmoTypeString = oup.getWmoType().upper()
|
||||
|
||||
# address
|
||||
address = oup.getAddress()
|
||||
if address == 'DEF' or address == 'ALL':
|
||||
address = 'DEFAULTNCF,NWWSUP'
|
||||
elif address is None:
|
||||
address = 'DEFAULTNCF,NWWSUP'
|
||||
|
||||
# source, possibly None
|
||||
source = oup.getSource()
|
||||
|
||||
# time stamp DDHHMM
|
||||
if oup.getUserDateTimeStamp():
|
||||
userDateTimeStamp = oup.getUserDateTimeStamp().upper()
|
||||
if len(userDateTimeStamp) != 6:
|
||||
msg = "Error: User date time stamp is wrong length\n"
|
||||
_Logger.error("User date time stamp is wrong length")
|
||||
resp.setMessage(msg)
|
||||
return
|
||||
|
||||
#----------
|
||||
# Initialize the product identifier
|
||||
#----------
|
||||
awipsWanPil = oup.getAwipsWanPil()
|
||||
_Logger.debug('awipsWanPil = ' + awipsWanPil)
|
||||
|
||||
#----------
|
||||
# Extract the category ( NNN of CCCCNNNXXX ) from the awips ID
|
||||
#----------
|
||||
prodCategory = getCategory(awipsWanPil)
|
||||
_Logger.debug("Product Category = " + prodCategory)
|
||||
|
||||
#----------
|
||||
# Determine the transmission priority for WAN distribution
|
||||
#----------
|
||||
priority = getPriority(prodCategory)
|
||||
oup.setPriority(priority)
|
||||
_Logger.debug('Priority = ' + str(priority))
|
||||
|
||||
#----------
|
||||
# Retrieve the contents of the product
|
||||
#----------
|
||||
contents = oup.getProductText()
|
||||
productId = contents.split('\n')[0].strip()
|
||||
|
||||
#----------
|
||||
# Locally store OUP in text database and archive
|
||||
#----------
|
||||
awipsPathname = createTargetFile(contents,
|
||||
OUT_DIR + '/' + oup.getFilename())
|
||||
if not awipsPathname:
|
||||
_Logger.debug('Unable to store product to text database:')
|
||||
storageCompleted = DB_FAILURE
|
||||
msg = 'Product ' + awipsWanPil + ' failed to be ingested and archived.\n'
|
||||
_Logger.debug(msg)
|
||||
resp.setMessage(msg)
|
||||
return
|
||||
elif not test:
|
||||
try:
|
||||
from com.raytheon.uf.edex.plugin.manualIngest import MessageGenerator
|
||||
if MessageGenerator.getInstance().sendFileToIngest(awipsPathname, INGEST_ROUTE):
|
||||
msg = 'Product ' + awipsWanPil + ' successfully ingested and archived locally.\n'
|
||||
resp.setSendLocalSuccess(True)
|
||||
_Logger.info(msg)
|
||||
else:
|
||||
msg = 'Product ' + awipsWanPil + ' failed to be ingested and archived.\n'
|
||||
resp.setMessage(msg)
|
||||
return
|
||||
except Exception, e:
|
||||
msg = 'Product ' + awipsWanPil + ' failed to be ingested and archived properly. Reason:\n' + str(e)
|
||||
resp.setMessage(msg)
|
||||
return
|
||||
|
||||
attachedFilename = oup.getAttachedFilename()
|
||||
attachedFile = oup.getAttachedFile()
|
||||
if attachedFilename and attachedFile:
|
||||
# spaces will screw up the command line string
|
||||
attachedFilename = attachedFilename.replace(" ", "")
|
||||
# dealing with a java byte[] so write it out with java
|
||||
from java.io import File, FileOutputStream
|
||||
attachedFilename = createTargetFile("", OUT_DIR + '/' + attachedFilename)
|
||||
f = File(attachedFilename)
|
||||
fos = FileOutputStream(f)
|
||||
fos.write(attachedFile)
|
||||
fos.flush()
|
||||
fos.close()
|
||||
|
||||
if test:
|
||||
try:
|
||||
os.remove(awipsPathname)
|
||||
except EnvironmentError:
|
||||
pass # ignore
|
||||
if attachedFilename:
|
||||
try:
|
||||
os.remove(attachedFilename)
|
||||
except EnvironmentError:
|
||||
pass # ignore
|
||||
|
||||
resp.setSendLocalSuccess(True)
|
||||
resp.setSendWANSuccess(True)
|
||||
return
|
||||
|
||||
messageIdToAcknowledge = None
|
||||
#----------
|
||||
# Check if product should be distributed over WAN via NCF
|
||||
#----------
|
||||
wmoID = contents[0:6]
|
||||
splitAddr = address.split(',')
|
||||
for addr in splitAddr:
|
||||
if addr != '000': # 000 is local only
|
||||
_Logger.info("Addressee is " + addr)
|
||||
#----------
|
||||
# Check if product should be sent to the NWWS for uplink
|
||||
#----------
|
||||
if (addr.find('NWWSUP') > -1):
|
||||
if isNWWSProduct(awipsWanPil, afosID, wmoID, SITE_ID):
|
||||
#----------
|
||||
# Send OUP to its designated NWWS primary and backup sites for up-link
|
||||
#----------
|
||||
code = "NWWS_UPLINK"
|
||||
if source and source == 'TextWS':
|
||||
code = "42"
|
||||
sendResult = sendWANMsg(productId, awipsPathname, addr, code,
|
||||
userDateTimeStamp, priority, wmoTypeString, source, resp, afosID, attachedFilename)
|
||||
if not sendResult:
|
||||
# failure of some kind so return
|
||||
return
|
||||
else:
|
||||
_Logger.debug("Product is not an NWWS product. Not sending product " +
|
||||
'over NWWS up-link.')
|
||||
else:
|
||||
if isLegalWANProduct(awipsWanPil, afosID, wmoID, SITE_ID):
|
||||
#----------
|
||||
# Send OUP to the NCF
|
||||
#----------
|
||||
code = "0"
|
||||
if addr == "DEFAULTNCF":
|
||||
code = "134"
|
||||
if source and source == 'TextWS':
|
||||
if (prodCategory == 'ADR' or prodCategory == 'ADM' or prodCategory == 'ADA') and \
|
||||
attachedFilename:
|
||||
code = "7"
|
||||
else:
|
||||
code = "4"
|
||||
|
||||
if prodCategory == 'FTM':
|
||||
_Logger.info("Sending FTM to the RPG")
|
||||
try:
|
||||
from com.raytheon.edex.rpgenvdata import RadarTextDataManager
|
||||
ftmReq = RadarTextDataManager(contents)
|
||||
ftmReq.sendRadarTextDataToRPGs()
|
||||
ftmReq.close()
|
||||
except Exception, e:
|
||||
result = "Error sending product FTM.\n" + str(e)
|
||||
_Logger.error(result)
|
||||
ftmReq.close()
|
||||
|
||||
sendResult = sendWANMsg(productId, awipsPathname, addr, code, userDateTimeStamp,
|
||||
priority, wmoTypeString, source, resp, afosID, attachedFilename)
|
||||
if not sendResult:
|
||||
# failure of some kind so return
|
||||
return
|
||||
# Copy this now as the values may change in another loop iteration
|
||||
if resp.getNeedAcknowledgment() and messageIdToAcknowledge is None:
|
||||
messageIdToAcknowledge = resp.getMessageId()
|
||||
else:
|
||||
_Logger.info("Product is not authorized for distribution.")
|
||||
_Logger.info("Not sending product to NCF.")
|
||||
msg = "Warning: Product is not authorized for distribution.\n"
|
||||
resp.setMessage(msg)
|
||||
return
|
||||
|
||||
if messageIdToAcknowledge:
|
||||
resp.setNeedAcknowledgment(True)
|
||||
resp.setMessageId(messageIdToAcknowledge)
|
||||
if ackMgr != None:
|
||||
_Logger.info("Waiting for acknowledgment of " + messageIdToAcknowledge)
|
||||
ackMgr.waitAck(messageIdToAcknowledge, address, resp,
|
||||
afosID + " " + userDateTimeStamp)
|
||||
_Logger.info("Finished waiting for acknowledgment of %s: %s" %
|
||||
(messageIdToAcknowledge, resp.isAcknowledged() and
|
||||
"ACK" or resp.getMessage()))
|
||||
if not resp.isAcknowledged():
|
||||
# Send ITO alarm
|
||||
ito_err = None
|
||||
try:
|
||||
ec = subprocess.call(['/opt/OV/bin/OpC/opcmsg', 'application=MHS', 'object=MHS',
|
||||
'msg_text=%s (msgid %s)' % (resp.getMessage(), messageIdToAcknowledge),
|
||||
'severity=Critical', 'msg_grp=AWIPS'])
|
||||
if ec != 0:
|
||||
ito_err = 'exit code = ' + str(ec)
|
||||
except:
|
||||
ito_err = str(sys.exc_info()[1])
|
||||
if ito_err is not None:
|
||||
_Logger.error("Error sending ITO alarm: " + ito_err)
|
||||
else:
|
||||
_Logger.error("Acknowledgment requirement, but ackMgr is None")
|
||||
|
||||
_Logger.debug('Script done....')
|
||||
return
|
||||
|
||||
|
||||
#---getCategory()--------------------------------------------------------------#
|
||||
#
|
||||
# Purpose:
|
||||
# Determines the product category from the AWIPS identifier.
|
||||
#
|
||||
# Parameters:
|
||||
# AWIPS product identifier (CCCCNNNXXX)
|
||||
#
|
||||
# Returns:
|
||||
# 3-letter product category (NNN of CCCCNNNXXX)
|
||||
#
|
||||
# Implementation:
|
||||
#
|
||||
#------------------------------------------------------------------------------#
|
||||
def getCategory(awipsID):
|
||||
_Logger.debug("getCategory():")
|
||||
return awipsID[4:7]
|
||||
|
||||
|
||||
#---getPriority()--------------------------------------------------------------#
|
||||
#
|
||||
# Purpose:
|
||||
# Returns the priority level of the product based on its category.
|
||||
#
|
||||
# Parameters:
|
||||
# 3 letter product category (NNN)
|
||||
#
|
||||
# Returns:
|
||||
# Priority level [0,1,2] where 2 = highest
|
||||
#
|
||||
# Implementation:
|
||||
# Searches awipsPriorities.txt using the product category as the key.
|
||||
# If the file does not contain the specified category entry, the lowest
|
||||
# priority level is assumed.
|
||||
# Exits program if file cannot be opened.
|
||||
#
|
||||
#------------------------------------------------------------------------------#
|
||||
def getPriority(nnn):
|
||||
_Logger.debug('getPriority():')
|
||||
|
||||
priority = "0"
|
||||
path = pathMgr.getStaticFile(DISSEMINATION_DIR + 'awipsPriorities.txt').getPath()
|
||||
pfile = open(path, 'r')
|
||||
for line in pfile:
|
||||
if nnn == line[0:3]:
|
||||
_Logger.debug(line)
|
||||
priority = line[4:].strip()
|
||||
break
|
||||
pfile.close()
|
||||
|
||||
priority = int(priority)
|
||||
return priority
|
||||
|
||||
#---isLegalWANProduct()------------------------------------------------------#
|
||||
#
|
||||
# Purpose:
|
||||
# Determines whether the product is a valid NWWS product.
|
||||
#
|
||||
# Parameters:
|
||||
# AWIPS identifier (CCCCNNNXXX)
|
||||
# AFOS identifier (CCCNNNXXX)
|
||||
# WMO identifier (TTAAII)
|
||||
#
|
||||
# Returns:
|
||||
# 1 (TRUE)/ 0 (FALSE)
|
||||
#
|
||||
# Implementation:
|
||||
# Reads the site-specific WAN exclusionary list which contains a
|
||||
# list of product ids representing products which are not meant for
|
||||
# distribution over WAN via NCF. The AWIPS id, the AFOS id,
|
||||
# and the WMO id, are acceptable representations of the product id.
|
||||
#
|
||||
# If the exclusionary file either does not exist, is empty, or cannot
|
||||
# be read, then the product will be distributed.
|
||||
#
|
||||
# Program exits if the site id environment variable (FXA_LOCAL_SITE)
|
||||
# is undefined.
|
||||
#
|
||||
#------------------------------------------------------------------------------#
|
||||
def isLegalWANProduct(myAwipsId, myAfosId, myWmoId, siteID):
|
||||
_Logger.debug('isLegalWANProduct():')
|
||||
|
||||
# Read the WAN exclusionary file
|
||||
fileName = 'WAN_exclude_' + siteID + '.txt'
|
||||
locFile = pathMgr.getStaticFile(DISSEMINATION_DIR + fileName)
|
||||
filePath = None
|
||||
if locFile is not None:
|
||||
filePath = locFile.getPath()
|
||||
if filePath is not None and os.path.isfile(filePath):
|
||||
wanExcludeFile = open(filePath, 'r')
|
||||
for line in wanExcludeFile:
|
||||
if not line.startswith('#'):
|
||||
productId = line.strip()
|
||||
if productId == myAwipsId or productId == myAfosId or productId == myWmoId:
|
||||
_Logger.info('Product found in WAN exclude list as ' + productId)
|
||||
wanExcludeFile.close()
|
||||
return False
|
||||
# Otherwise, product did not appear on the exclude list and therefore,
|
||||
# product is meant for distribution
|
||||
_Logger.info(myAwipsId + ' is a legal WAN product.')
|
||||
wanExcludeFile.close()
|
||||
return True
|
||||
else:
|
||||
_Logger.info(fileName + ' does not exist or is empty. Sending ' +
|
||||
'product over WAN.')
|
||||
return True
|
||||
|
||||
|
||||
#---sendWANMsg()---------------------------------------------------------------#
|
||||
#
|
||||
# Purpose:
|
||||
# Distributes an OUP to a specified receiving site over the WAN.
|
||||
#
|
||||
# Parameters:
|
||||
# receiving site
|
||||
# handling action to take on product at the receiving site
|
||||
# additional option string
|
||||
#
|
||||
# Returns:
|
||||
# 1 (TRUE) = successful message submission
|
||||
# 0 (FALSE) = unsuccessful message submission
|
||||
#
|
||||
# Implementation:
|
||||
# Uses system() function to execute the distributeProduct program.
|
||||
#
|
||||
#------------------------------------------------------------------------------#
|
||||
def sendWANMsg(productId, prodPathName, receivingSite, handling,
|
||||
userDateTimeStamp, priority, wmoTypeString, source, resp, subject=None, attachedFilename=None):
|
||||
# _Logger.debug('sendWANMsg():')
|
||||
_Logger.info('sendWANMsg ' + str(prodPathName) + ' addr=' + str(receivingSite) + \
|
||||
' code=' + str(handling) + ' source=' + str(source))
|
||||
|
||||
try:
|
||||
code = int(handling)
|
||||
except:
|
||||
code = int(ACTION_CODES[handling])
|
||||
# set acknowledgment from receiver if message is high priority and is from TextWS
|
||||
# resp = OUPResponse()
|
||||
|
||||
|
||||
from com.raytheon.messaging.mhs import MhsMessage, MhsMessagePriority, MhsSubmitException
|
||||
mhsMsg = MhsMessage(code)
|
||||
|
||||
if subject:
|
||||
mhsMsg.setSubject(subject)
|
||||
|
||||
if attachedFilename:
|
||||
mhsMsg.addEnclosure(attachedFilename)
|
||||
|
||||
#mhsMsg.setBodyFile(prodPathName)
|
||||
mhsMsg.addEnclosure(prodPathName)
|
||||
if priority == 0:
|
||||
jpriority = MhsMessagePriority.Default
|
||||
elif priority == 1:
|
||||
jpriority = MhsMessagePriority.Medium
|
||||
elif priority == 2:
|
||||
jpriority = MhsMessagePriority.High
|
||||
mhsMsg.setPriority(jpriority)
|
||||
|
||||
if priority == 2 and source == "TextWS":
|
||||
resp.setNeedAcknowledgment(True)
|
||||
mhsMsg.addAckAddressee(receivingSite)
|
||||
mhsMsg.setTimeoutTime(300)
|
||||
else:
|
||||
# No need to get acknowledgment from receiver
|
||||
resp.setNeedAcknowledgment(False)
|
||||
mhsMsg.addAddressee(receivingSite)
|
||||
|
||||
_Logger.info("Calling mhsMsg.send()")
|
||||
result = mhsMsg.send()
|
||||
|
||||
if not result:
|
||||
result = "Error sending product " + productId + " to " + receivingSite + ". Check server logs for more detail.\n"
|
||||
_Logger.error(result)
|
||||
resp.setSendWANSuccess(False)
|
||||
resp.setMessage(result)
|
||||
return False
|
||||
else:
|
||||
resp.setSendWANSuccess(True)
|
||||
if resp.getNeedAcknowledgment():
|
||||
resp.setMessageId(result)
|
||||
|
||||
_Logger.info("Successful send of " + str(result))
|
||||
return True
|
||||
|
||||
|
||||
#---isNWWSProduct()------------------------------------------------------------#
|
||||
#
|
||||
# Purpose:
|
||||
# Determines whether the product is a valid NWWS product.
|
||||
#
|
||||
# Parameters:
|
||||
# AWIPS identifier (CCCCNNNXXX)
|
||||
# AFOS identifier (CCCNNNXXX)
|
||||
# WMO identifier (TTAAII)
|
||||
#
|
||||
# Returns:
|
||||
# 1 (TRUE)/ 0 (FALSE)
|
||||
#
|
||||
# Implementation:
|
||||
# Reads the site-specific NWWS exclusionary list which contains a
|
||||
# list of product ids representing products which are not meant for
|
||||
# distribution over the NWWS up-link. The AWIPS id, the AFOS id,
|
||||
# and the WMO id, are acceptable representations of the product id.
|
||||
#
|
||||
# If the exclusionary file either does not exist, is empty, or cannot
|
||||
# be read, then the product will be uplink.
|
||||
#
|
||||
# Program exits if the site id environment variable (FXA_LOCAL_SITE)
|
||||
# is undefined.
|
||||
#
|
||||
# This module addresses DR 5191.
|
||||
#
|
||||
#------------------------------------------------------------------------------#
|
||||
def isNWWSProduct(myAwipsId, myAfosId, myWmoId, siteID):
|
||||
_Logger.debug('isNWWSProduct():\n')
|
||||
|
||||
# Read the NWWS exclusionary file
|
||||
fileName = 'NWWS_exclude_' + siteID + '.txt'
|
||||
locFile = pathMgr.getStaticFile(DISSEMINATION_DIR + fileName)
|
||||
filePath = None
|
||||
if locFile is not None:
|
||||
filePath = locFile.getPath()
|
||||
if filePath is not None and os.path.isfile(filePath):
|
||||
nwwsExcludeFile = open(filePath, 'r')
|
||||
for line in nwwsExcludeFile:
|
||||
# If entry is found, then product should not be distributed
|
||||
# over the NWWS uplink
|
||||
if not line.startswith('#'): # skips comment lines
|
||||
productId = line.strip()
|
||||
if productId == myAwipsId or productId == myAfosId or productId == myWmoId:
|
||||
_Logger.info('Product found in NWWS exclude list as ' + productId)
|
||||
nwwsExcludeFile.close()
|
||||
return False
|
||||
# Otherwise, product did not appear on the exclude list and therefore,
|
||||
# product is meant for distribution
|
||||
_Logger.info(myAwipsId + ' is an NWWS product.')
|
||||
nwwsExcludeFile.close()
|
||||
return True
|
||||
else:
|
||||
_Logger.info(fileName + ' does not exist or is empty. Sending ' +
|
||||
'product over NWWS uplink.')
|
||||
return True
|
||||
|
||||
|
||||
|
||||
|
||||
#---createTargetFile()---------------------------------------------------------#
|
||||
#
|
||||
# Purpose:
|
||||
# Creates a product file in the named target directory with a selected
|
||||
# communications header for identification.
|
||||
#
|
||||
# Parameters:
|
||||
# communications header
|
||||
# product contents
|
||||
# target product pathname (Output)
|
||||
#
|
||||
# Returns:
|
||||
# The output path (which may differ from targetPathname)
|
||||
#
|
||||
# Implementation:
|
||||
#
|
||||
#------------------------------------------------------------------------------#
|
||||
def createTargetFile(fileData, targetPathname):
|
||||
_Logger.debug('createTargetFile():')
|
||||
_Logger.debug('target product pathname = ' + targetPathname)
|
||||
|
||||
pathToUse = targetPathname
|
||||
i = 0
|
||||
while True:
|
||||
try:
|
||||
fd = os.open(pathToUse, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0666)
|
||||
except OSError, e:
|
||||
if e.errno == errno.EEXIST:
|
||||
i += 1
|
||||
pathToUse = targetPathname + '.' + str(i)
|
||||
continue
|
||||
raise e
|
||||
else:
|
||||
break
|
||||
|
||||
if i > 0:
|
||||
_Logger.info('Renamed target file to ' + pathToUse)
|
||||
|
||||
outFile = os.fdopen(fd, 'w')
|
||||
outFile.write(fileData)
|
||||
outFile.flush()
|
||||
outFile.close()
|
||||
return pathToUse
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
TEST_ECHO 128
|
||||
AFOS_STORE_TEXTDB 129
|
||||
AWIPS_STORE_TEXTDB 130
|
||||
NWWS_UPLINK 131
|
||||
RIVPROD_CRS 132
|
||||
SHEFPRODUCT 133
|
||||
INTERSITE_STORE 134
|
||||
HYDRO_MODEL_DATA 135
|
||||
RIVPROD_BACKUP 136
|
||||
RADAR_PRECIP_BIAS 137
|
Loading…
Add table
Reference in a new issue