/*
* Copyright(c) 2005 Center for E-Commerce Infrastructure Development, The
* University of Hong Kong (HKU). All Rights Reserved.
*
* This software is licensed under the GNU GENERAL PUBLIC LICENSE Version 2.0 [1]
*
* [1] http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*/
package hk.hku.cecid.edi.as2.module;
import hk.hku.cecid.edi.as2.AS2Exception;
import hk.hku.cecid.edi.as2.AS2Processor;
import hk.hku.cecid.edi.as2.dao.AS2DAOHandler;
import hk.hku.cecid.edi.as2.dao.MessageDVO;
import hk.hku.cecid.edi.as2.dao.PartnershipDVO;
import hk.hku.cecid.edi.as2.dao.RepositoryDVO;
import hk.hku.cecid.edi.as2.pkg.AS2Header;
import hk.hku.cecid.edi.as2.pkg.AS2Message;
import hk.hku.cecid.edi.as2.pkg.DispositionNotificationOption;
import hk.hku.cecid.piazza.commons.module.ActiveTask;
import hk.hku.cecid.piazza.commons.security.KeyStoreManager;
import hk.hku.cecid.piazza.commons.security.SMimeException;
import hk.hku.cecid.piazza.commons.security.SMimeMessage;
import javax.activation.FileDataSource;
/**
* OutgoingPayloadTask
*
* @author Hugo Y. K. Lam
*
*/
public class OutgoingPayloadTask implements ActiveTask {
// private int retried;
private PayloadCache payload;
/**
* @throws AS2Exception
*
*/
public OutgoingPayloadTask(PayloadCache payload) throws AS2Exception {
try {
if (payload == null) {
throw new AS2Exception("No payload data");
}
this.payload = payload;
if (!this.payload.checkOut()) {
throw new AS2Exception("Unable to check out payload: "+payload);
}
}
catch (Exception e) {
throw new AS2Exception("Unable to construct outgoing payload task", e);
}
}
/**
* execute
* @throws Exception
* @see hk.hku.cecid.piazza.commons.module.ActiveTask#execute()
*/
public void execute() throws Exception {
AS2DAOHandler daoHandler = new AS2DAOHandler(AS2Processor.core.dao);
AS2Message as2Message = new AS2Message();
as2Message.setMessageID(payload.getMessageID());
as2Message.setFromPartyID(payload.getFromPartyID());
as2Message.setToPartyID(payload.getToPartyID());
PartnershipDVO partnership = daoHandler.findPartnership(as2Message, false);
FileDataSource cacheSource = new FileDataSource(payload.getCache());
as2Message.setHeader(AS2Header.SUBJECT, partnership.getSubject());
as2Message.setContent(cacheSource, payload.getContentType());
String micAlg = null;
if (partnership.isReceiptRequired()) {
String returnUrl = null;
if (!partnership.isSyncReply()) {
returnUrl = partnership.getReceiptAddress();
}
if (partnership.isReceiptSignRequired()) {
micAlg = partnership.getMicAlgorithm();
}
as2Message.requestReceipt(returnUrl, micAlg);
}
KeyStoreManager keyman = AS2Processor.getKeyStoreManager();
SMimeMessage smime = new SMimeMessage(as2Message.getBodyPart(), keyman.getX509Certificate(), keyman.getPrivateKey());
smime.setContentTransferEncoding(SMimeMessage.CONTENT_TRANSFER_ENC_BINARY);
String mic = calculateMIC(smime, partnership);
if (partnership.isOutboundCompressRequired()) {
AS2Processor.core.log.info("Compressing outbound "+as2Message);
smime = smime.compress();
if (partnership.isOutboundSignRequired()) {
mic = calculateMIC(smime, partnership);
}
}
if (partnership.isOutboundSignRequired()) {
AS2Processor.core.log.info("Signing outbound "+as2Message);
String alg = partnership.getSignAlgorithm();
if (alg != null && alg.equalsIgnoreCase(PartnershipDVO.ALG_SIGN_MD5)) {
smime.setDigestAlgorithm(SMimeMessage.DIGEST_ALG_MD5);
}
else {
smime.setDigestAlgorithm(SMimeMessage.DIGEST_ALG_SHA1);
}
smime = smime.sign();
}
if (partnership.isOutboundEncryptRequired()) {
AS2Processor.core.log.info("Encrypting outbound "+as2Message);
String alg = partnership.getEncryptAlgorithm();
if (alg != null && alg.equalsIgnoreCase(PartnershipDVO.ALG_ENCRYPT_RC2)) {
smime.setEncryptAlgorithm(SMimeMessage.ENCRYPT_ALG_RC2_CBC);
}
else {
smime.setEncryptAlgorithm(SMimeMessage.ENCRYPT_ALG_DES_EDE3_CBC);
}
smime = smime.encrypt(partnership.getEncryptX509Certificate());
}
as2Message.setBodyPart(smime.getBodyPart());
AS2Processor.core.log.info("Persisting outbound "+as2Message);
RepositoryDVO repositoryDVO = daoHandler.createRepositoryDVO(as2Message, false);
MessageDVO messageDVO = daoHandler.createMessageDVO(as2Message, false);
messageDVO.setStatus(MessageDVO.STATUS_PENDING);
messageDVO.setMicValue(mic);
/* Capture the outgoing message */
AS2Processor.core.log.debug(as2Message + " is being captured");
AS2Processor.getMessageRepository().persistMessage(as2Message);
daoHandler.createMessageStore().storeMessage(messageDVO, repositoryDVO);
cacheSource = null;
AS2Processor.core.log.debug("Clearing cache of "+as2Message+": "+payload.clear());
}
private String calculateMIC(SMimeMessage smime, PartnershipDVO partnership) throws SMimeException {
String mic = null;
if (partnership.isReceiptSignRequired()) {
boolean isSMime = partnership.isOutboundCompressRequired() ||
partnership.isOutboundSignRequired() ||
partnership.isOutboundEncryptRequired();
String micAlg = partnership.getMicAlgorithm();
if (micAlg !=null && micAlg.equalsIgnoreCase(PartnershipDVO.ALG_MIC_MD5)) {
mic = smime.digest(SMimeMessage.DIGEST_ALG_MD5, isSMime);
micAlg = DispositionNotificationOption.SIGNED_RECEIPT_MICALG_MD5;
}
else {
mic = smime.digest(SMimeMessage.DIGEST_ALG_SHA1, isSMime);
micAlg = DispositionNotificationOption.SIGNED_RECEIPT_MICALG_SHA1;
}
mic = mic + ", " + micAlg;
}
return mic;
}
/**
* onFailure
* @param e
* @see hk.hku.cecid.piazza.commons.module.ActiveTask#onFailure(java.lang.Throwable)
*/
public void onFailure(Throwable e) {
AS2Processor.core.log.error("Outgoing payload task failure", e);
}
/**
* isRetryEnabled
* @return boolean
* @see hk.hku.cecid.piazza.commons.module.ActiveTask#isRetryEnabled()
*/
public boolean isRetryEnabled() {
return false;
}
/**
* getRetryInterval
* @return long
* @see hk.hku.cecid.piazza.commons.module.ActiveTask#getRetryInterval()
*/
public long getRetryInterval() {
return -1;
}
/**
* getMaxRetries
* @return int
* @see hk.hku.cecid.piazza.commons.module.ActiveTask#getMaxRetries()
*/
public int getMaxRetries() {
return 0;
}
/**
* setRetried
* @param retried
* @see hk.hku.cecid.piazza.commons.module.ActiveTask#setRetried(int)
*/
public void setRetried(int retried) {
// this.retried = retried;
}
/**
* onAwake
*
* @see hk.hku.cecid.piazza.commons.module.ActiveTask#onAwake()
*/
public void onAwake() {
}
/**
* isSucceedFast
* @return boolean
* @see hk.hku.cecid.piazza.commons.module.ActiveTask#isSucceedFast()
*/
public boolean isSucceedFast() {
return true;
}
}