rm edexOsgi/com.raytheon.uf.edex.dissemination

This commit is contained in:
mjames-upc 2018-07-20 10:17:25 -06:00
parent 83af442096
commit 20cb5cebc8
20 changed files with 0 additions and 2111 deletions

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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

View file

@ -1,6 +0,0 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
utility/,\
.,\
res/

View file

@ -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>

View file

@ -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&amp;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>

View file

@ -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();
}
}

View file

@ -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();
}
}
}

View file

@ -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());
}
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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";
}

View file

@ -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();
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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

View file

@ -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

View file

@ -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