//$Header: /cvsroot-fuse/mec-as2/39/mendelson/comm/as2/message/ExecuteShellCommand.java,v 1.1 2012/04/18 14:10:30 heller Exp $
package de.mendelson.comm.as2.message;
import de.mendelson.comm.as2.log.LogAccessDB;
import de.mendelson.comm.as2.log.LogEntry;
import de.mendelson.comm.as2.partner.Partner;
import de.mendelson.comm.as2.partner.PartnerAccessDB;
import de.mendelson.comm.as2.server.AS2Server;
import de.mendelson.util.Exec;
import de.mendelson.util.MecResourceBundle;
import java.io.File;
import java.io.PrintStream;
import java.sql.Connection;
import java.util.List;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
/*
* Copyright (C) mendelson-e-commerce GmbH Berlin Germany
*
* This software is subject to the license agreement set forth in the license.
* Please read and agree to all terms before using this software.
* Other product and brand names are trademarks of their respective owners.
*/
/**
* Allows to execute a shell command. This is used to execute a shell command on
*message receipt
* @author S.Heller
* @version $Revision: 1.1 $
*/
public class ExecuteShellCommand {
private Logger logger = Logger.getLogger(AS2Server.SERVER_LOGGER_NAME);
private MessageAccessDB messageAccess;
/**Localize your GUI!*/
private MecResourceBundle rb = null;
//DB connection
private Connection runtimeConnection;
private Connection configConnection;
public ExecuteShellCommand(Connection configConnection, Connection runtimeConnection) {
this.runtimeConnection = runtimeConnection;
this.configConnection = configConnection;
this.messageAccess = new MessageAccessDB(configConnection, runtimeConnection);
//Load resourcebundle
try {
this.rb = (MecResourceBundle) ResourceBundle.getBundle(
ResourceBundleExecuteShellCommand.class.getName());
} //load up resourcebundle
catch (MissingResourceException e) {
throw new RuntimeException("Oops..resource bundle " + e.getClassName() + " not found.");
}
}
/**Executes a shell command for an inbound AS2 message if this has been defined in the partner settings
*/
public void executeShellCommandOnSend(AS2MessageInfo messageInfo, AS2MDNInfo mdnInfo) {
//do not execute a command for CEM messages
if (messageInfo.getMessageType() == AS2Message.MESSAGETYPE_CEM) {
return;
}
PartnerAccessDB partnerAccess = new PartnerAccessDB(this.configConnection, this.runtimeConnection);
Partner messageSender = partnerAccess.getPartner(messageInfo.getSenderId());
Partner messageReceiver = partnerAccess.getPartner(messageInfo.getReceiverId());
List<AS2Payload> payload = this.messageAccess.getPayload(messageInfo.getMessageId());
String rawCommand = null;
if (messageInfo.getState() == AS2Message.STATE_FINISHED) {
if (!messageReceiver.useCommandOnSendSuccess()) {
return;
} else {
rawCommand = messageReceiver.getCommandOnSendSuccess();
//empty command?
if (rawCommand == null || rawCommand.trim().length() == 0) {
return;
}
}
} else if (messageInfo.getState() == AS2Message.STATE_STOPPED) {
if (!messageReceiver.useCommandOnSendError()) {
return;
} else {
rawCommand = messageReceiver.getCommandOnSendError();
//empty command, huh?
if (rawCommand == null || rawCommand.trim().length() == 0) {
return;
}
}
} else {
//state:pending should not execute anything
return;
}
if (payload != null && payload.size() > 0) {
this.logger.log(Level.INFO, this.rb.getResourceString("executing.send", messageInfo.getMessageId()), messageInfo);
for (AS2Payload singlePayload : payload) {
if (singlePayload.getPayloadFilename() == null) {
this.logger.warning("executeShellCommandOnSend: payload filename does not exist.");
continue;
}
String filename = singlePayload.getOriginalFilename();
String command = this.replace(rawCommand, "${filename}", filename);
command = this.replace(command, "${fullstoragefilename}", singlePayload.getPayloadFilename());
command = this.replace(command, "${sender}", messageSender.getName());
command = this.replace(command, "${receiver}", messageReceiver.getName());
command = this.replace(command, "${messageid}", messageInfo.getMessageId());
if (messageInfo.getSubject() != null) {
command = this.replace(command, "${subject}", messageInfo.getSubject());
} else {
command = this.replace(command, "${subject}", "");
}
if (mdnInfo != null) {
command = this.replace(command, "${mdntext}", mdnInfo.getRemoteMDNText());
} else {
command = this.replace(command, "${mdntext}", "");
}
//add log?
if (command.contains("${log}")) {
try {
LogAccessDB logAccess = new LogAccessDB(this.configConnection, this.runtimeConnection);
LogEntry[] entries = logAccess.getLog(messageInfo.getMessageId());
StringBuilder logBuffer = new StringBuilder();
for (LogEntry logEntry : entries) {
logBuffer.append(logEntry.getMessage()).append("\\n");
}
//dont use single and double quotes, this is used in command line environment
String logText = this.replace(logBuffer.toString(), "\"", "");
logText = this.replace(logText, "'", "");
command = this.replace(command, "${log}", logText);
} catch (Exception e) {
this.logger.warning(e.getMessage());
}
}
this.logger.log(Level.INFO, this.rb.getResourceString("executing.command",
new Object[]{messageInfo.getMessageId(), command}), messageInfo);
Exec exec = new Exec();
try {
int returnCode = exec.start(command, new PrintStream(new AS2LoggerOutputStream(this.logger, messageInfo)),
new PrintStream(new AS2LoggerOutputStream(this.logger, messageInfo)));
this.logger.log(Level.INFO, this.rb.getResourceString("executed.command",
new Object[]{messageInfo.getMessageId(), String.valueOf(returnCode)}), messageInfo);
} catch (Exception e) {
this.logger.warning(e.getMessage());
}
}
} else {
this.logger.warning("executeShellCommandOnSend: No payload found for message " + messageInfo.getMessageId());
}
}
/**Executes a shell command for an inbound AS2 message if this has been defined in the partner settings
*/
public void executeShellCommandOnReceipt(Partner messageSender, Partner messageReceiver, AS2MessageInfo messageInfo) {
//do not execute a command for CEM messages
if (messageInfo.getMessageType() == AS2Message.MESSAGETYPE_CEM) {
return;
}
if (!messageSender.useCommandOnReceipt()) {
return;
}
if (messageSender.getCommandOnReceipt() == null || messageSender.getCommandOnReceipt().trim().length() == 0) {
return;
}
List<AS2Payload> payload = this.messageAccess.getPayload(messageInfo.getMessageId());
if (payload != null) {
this.logger.log(Level.INFO, this.rb.getResourceString("executing.receipt", messageInfo.getMessageId()), messageInfo);
for (int i = 0; i < payload.size(); i++) {
if (payload.get(i).getPayloadFilename() == null) {
continue;
}
String filename = payload.get(i).getPayloadFilename();
String command = this.replace(messageSender.getCommandOnReceipt(), "${filename}",
new File(filename).getAbsolutePath());
command = this.replace(command, "${sender}", messageSender.getName());
command = this.replace(command, "${receiver}", messageReceiver.getName());
command = this.replace(command, "${messageid}", messageInfo.getMessageId());
if (messageInfo.getSubject() != null) {
command = this.replace(command, "${subject}", messageInfo.getSubject());
} else {
command = this.replace(command, "${subject}", "");
}
this.logger.log(Level.INFO, this.rb.getResourceString("executing.command",
new Object[]{messageInfo.getMessageId(), command}), messageInfo);
Exec exec = new Exec();
try {
int returnCode = exec.start(command, new PrintStream(new AS2LoggerOutputStream(this.logger, messageInfo)),
new PrintStream(new AS2LoggerOutputStream(this.logger, messageInfo)));
this.logger.log(Level.INFO, this.rb.getResourceString("executed.command",
new Object[]{messageInfo.getMessageId(), String.valueOf(returnCode)}), messageInfo);
} catch (Exception e) {
this.logger.warning(e.getMessage());
}
}
}
}
/** Replaces the string tag by the string replacement in the sourceString
* @param source Source string
* @param tag String that will be replaced
* @param replacement String that will replace the tag
* @return String that contains the replaced values
*/
private String replace(String source, String tag, String replacement) {
if (source == null) {
return null;
}
StringBuilder buffer = new StringBuilder();
while (true) {
int index = source.indexOf(tag);
if (index == -1) {
buffer.append(source);
return (buffer.toString());
}
buffer.append(source.substring(0, index));
buffer.append(replacement);
source = source.substring(index + tag.length());
}
}
}