/* * 著作権表記 TODO 要否をお客様に確認 */ package com.pgf.mqspring.service.impl; import java.text.MessageFormat; import java.util.Arrays; import javax.jms.BytesMessage; import javax.jms.JMSException; import javax.xml.bind.DatatypeConverter; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.jms.core.JmsTemplate; import org.springframework.stereotype.Service; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.pgf.mqspring.component.CharacterCodeConverterComponent; import com.pgf.mqspring.component.MqSpringMessageSourceComponent; import com.pgf.mqspring.constant.MqSpringConst; import com.pgf.mqspring.constant.MqSpringMessageId; import com.pgf.mqspring.exception.MqSpringException; import com.pgf.mqspring.model.ReplyResponseModel; import com.pgf.mqspring.model.SendMapVectorRequestModel; import com.pgf.mqspring.service.MqReceiveService; /** * MQ受信用サービス実装クラス *
* 指定されたキューからメッセージを受信する。 */ @Service public class MqReceiveServiceImpl implements MqReceiveService { /** JMSテンプレート */ private JmsTemplate jmsTemplate = null; /** キュー */ private String queue = MqSpringConst.BLANK; /** 文字コード変換クラス */ @Autowired private CharacterCodeConverterComponent characterCodeConverter; /** MqSpringメッセージソースクラス */ @Autowired private MqSpringMessageSourceComponent messageSource; /** オブジェクトマッパー */ private ObjectMapper mapper = new ObjectMapper(); /** ロガー */ Logger logger = LogManager.getLogger(); /** メッセージセレクターフォーマット */ private static final String MESSAGE_SELECTOR_FORMAT = "JMSCorrelationID = ''{0}''"; /** * MQ受信用サービス実装クラスのコンストラクタ * * @param template Jmsテンプレート */ public MqReceiveServiceImpl(JmsTemplate template) { this.jmsTemplate = template; } /** * メッセージ受信処理 *
* 受信用キューから条件に合致したメッセージを取得する。以下引数
* ・キュー
* ・JMS相関ID
* 取得したメッセージがnullの場合
* エラーログを出力する。以下引数
* ・メッセージID:SYS7008E
* MqSpringExceptionの例外をスローする。以下引数
* ・メッセージID:SYS7008E
* ・HttpStatus:REQUEST_TIMEOUT
* バイト配列の受信電文をレスポンス用モデルクラスに格納する。
* 受信メッセージの文字コードをEBCDICからSJISに変換する。
* レスポンス用モデルクラスをJSON形式に変換して返却する。
* メッセージ受信処理でMqSpringExceptionが発生した場合
* キャッチした内容をそのままスローする。
* メッセージ受信処理でJMS例外が発生した場合
* エラーログを出力する。以下引数
* ・メッセージID:SYS7006E
* ・発生した例外:JMSException
* MqSpringExceptionの例外をスローする。以下引数
* ・メッセージID:SYS7006E
* ・HttpStatus:REQUEST_TIMEOUT
* JSON形式に変換する際に例外が発生した場合
* エラーログを出力する。以下引数
* ・メッセージID:SYS7080E
* ・発生した例外:JsonProcessingException
* MqSpringExceptionの例外をスローする。以下引数
* ・メッセージID:SYS7080E
* ・HttpStatus:INTERNAL_SERVER_ERROR
* メッセージ受信処理で例外が発生した場合
* エラーログを出力する。以下引数
* ・メッセージID:SYS7072E
* ・発生した例外:Exception
* MqSpringExceptionの例外をスローする。以下引数
* ・メッセージID:SYS7072E
* ・HttpStatus:INTERNAL_SERVER_ERROR
*
* @param id メッセージID
* @return 返信レスポンス用モデルクラスのJSONデータ
*/
public String receiveMessage(String id) {
try {
logger.info("Message ID for Receive =" + id);
BytesMessage bm = (BytesMessage) jmsTemplate.receiveSelected(queue,
MessageFormat.format(MESSAGE_SELECTOR_FORMAT, id));
if (bm == null) {
logger.error(messageSource.getMessage(MqSpringMessageId.SYS7008E));
throw new MqSpringException(MqSpringMessageId.SYS7008E, HttpStatus.REQUEST_TIMEOUT);
}
byte[] bytes = bm.getBody(byte[].class);
logger.info("MQGET >>");
logger.info(DatatypeConverter.printHexBinary(bytes));
ReplyResponseModel response = editReplyData(bytes);
// MQMD
response.getMqmd().setCorrelId(bm.getJMSCorrelationID());
//Json変換
String json = MqSpringConst.BLANK;
json = mapper.writeValueAsString(response);
return json;
} catch (MqSpringException e) {
throw e;
} catch (JMSException ex) {
System.out.println(getStackTrace(ex));
logger.error(messageSource.getMessage(MqSpringMessageId.SYS7006E), ex);
throw new MqSpringException(MqSpringMessageId.SYS7006E, HttpStatus.REQUEST_TIMEOUT);
} catch (JsonProcessingException e) {
System.out.println(getStackTrace(e));
logger.error(messageSource.getMessage(MqSpringMessageId.SYS7080E), e);
throw new MqSpringException(MqSpringMessageId.SYS7080E, HttpStatus.INTERNAL_SERVER_ERROR);
} catch (Exception ex) {
System.out.println(getStackTrace(ex));
logger.error(messageSource.getMessage(MqSpringMessageId.SYS7072E), ex);
throw new MqSpringException(MqSpringMessageId.SYS7072E, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
/**
* 受信メッセージ編集処理
*
* 下記により各項目ごとにコード変換処理を行い、レスポンス用モデルクラスに設定する。
* ・16進文字列復号処理{@link characterCodeConverter#decodeHexStringData(byte[])}
* ・EBCDIC復号処理{@link characterCodeConverter#decodeEbcdic(byte[])}
* 引数のバイト配列が184より大きい場合
* Vector内の各項目ごとにコード変換処理を行い、レスポンス用モデルクラスに設定する。
* 引数のバイト配列が268より大きい場合
* Adsデータのコード変換処理を行い、レスポンス用モデルクラスに設定する。
*
* @param bytes バイト配列
* @return 返信レスポンス用モデルクラス
*/
public ReplyResponseModel editReplyData(byte[] bytes) {
ReplyResponseModel response = new ReplyResponseModel();
// MQCIH
response.getMqcih().setStrucId(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 0, 4)).trim());
response.getMqcih().setVersion(String.valueOf(
Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 4, 8)), 16)));
response.getMqcih().setStrucLength(String.valueOf(
Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 8, 12)), 16)));
response.getMqcih().setFormat(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 20, 28)));
response.getMqcih().setFlags(String.valueOf(
Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 28, 32)), 16)));
response.getMqcih().setReturnCode(String.valueOf(
Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 32, 36)), 16)));
response.getMqcih().setCompCode(String.valueOf(
Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 36, 40)), 16)));
response.getMqcih().setReason(String.valueOf(
Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 40, 44)), 16)));
response.getMqcih().setUowControl(String.valueOf(
Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 44, 48)), 16)));
response.getMqcih().setGetWaitInterval(String.valueOf(
Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 48, 52)), 16)));
response.getMqcih().setLinkType(String.valueOf(
Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 52, 56)), 16)));
response.getMqcih().setOutputDataLength(String.valueOf(
Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 56, 60)), 16)));
response.getMqcih().setFacilityKeepTime(String.valueOf(
Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 60, 64)), 16)));
response.getMqcih().setAdsDescriptor(String.valueOf(
Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 64, 68)), 16)));
response.getMqcih().setConversationalTask(String.valueOf(
Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 68, 72)), 16)));
response.getMqcih().setTaskEndStatus(String.valueOf(
Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 72, 76)), 16)));
response.getMqcih().setFacility(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 76, 84)));
response.getMqcih().setFunction(String.valueOf(
Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 84, 88)), 16)));
response.getMqcih().setAbendCode(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 88, 92)).trim());
response.getMqcih().setAutherticator(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 92, 100)));
response.getMqcih()
.setReplyToFormat(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 108, 116)).trim());
String transactionId = characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 124, 128));
response.getMqcih().setTransactionId(transactionId);
response.getMqcih()
.setFacilityLike(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 128, 132)).trim());
response.getMqcih()
.setAttentionId(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 132, 136)).trim());
response.getMqcih()
.setStartCode(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 136, 140)).trim());
response.getMqcih()
.setCancelCode(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 140, 144)).trim());
response.getMqcih()
.setNextTransactionCode(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 144, 148)));
response.getMqcih().setCursorPositon(String.valueOf(
Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 164, 168)), 16)));
response.getMqcih().setErrorOffset(String.valueOf(
Long.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 168, 172)), 16)));
// Vector
if (bytes.length > 184) {
SendMapVectorRequestModel sendMapVectorModel = new SendMapVectorRequestModel();
sendMapVectorModel
.setVectorDescriptor(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 184, 188)));
sendMapVectorModel.setVectorType(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 188, 189)));
sendMapVectorModel.setVectorVersion(String.valueOf(Long
.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 189, 196)), 16)));
sendMapVectorModel
.setScEraseIndic(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 196, 200)).trim());
sendMapVectorModel.setScEraseaupIndic(
characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 200, 204)).trim());
sendMapVectorModel
.setScFreekbIndic(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 204, 208)).trim());
sendMapVectorModel
.setScAlarmIndic(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 208, 212)).trim());
sendMapVectorModel
.setScFrsetIndic(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 212, 216)).trim());
sendMapVectorModel
.setScLastIndic(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 216, 220)).trim());
sendMapVectorModel
.setScWaitIndic(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 220, 224)).trim());
sendMapVectorModel.setScCursor(characterCodeConverter
.decodeHexStringData(Arrays.copyOfRange(bytes, 224, 228)).replaceAll("FFFFFFFF", "-1"));
sendMapVectorModel
.setScMsrData(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 228, 232)));
sendMapVectorModel
.setSmMapset(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 232, 240)).trim());
sendMapVectorModel
.setSmMap(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 240, 248)).trim());
sendMapVectorModel
.setSmDataIndic(characterCodeConverter.decodeEbcdic(Arrays.copyOfRange(bytes, 248, 252)).trim());
sendMapVectorModel.setSmDataLen(String.valueOf(Long
.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 252, 256)), 16)));
sendMapVectorModel.setSmDataOffset(String.valueOf(Long
.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 256, 260)), 16)));
sendMapVectorModel.setSmAdsdLen(String.valueOf(Long
.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 260, 264)), 16)));
sendMapVectorModel.setSmAdsdOffset(String.valueOf(Long
.parseLong(characterCodeConverter.decodeHexStringData(Arrays.copyOfRange(bytes, 264, 268)), 16)));
response.getReceiveMessage().setSendMapVector(sendMapVectorModel);
}
// Ads Data
if (bytes.length > 268) {
response.getReceiveMessage()
.setAds(characterCodeConverter
.decodeAdsData(transactionId, Arrays.copyOfRange(bytes, 268, bytes.length))
.replaceAll("\\u0000", ""));
}
return response;
}
/**
* キュー取得
*
* キューを返却する * * @return キュー */ public String getQueue() { return queue; } /** * キュー設定 *
* キューを設定する * * @param que キュー * @return 無し */ public void setQueue(String que) { queue = que; } private static String getStackTrace(Exception e) { StackTraceElement[] list = e.getStackTrace(); StringBuilder b = new StringBuilder(); b.append(e.getClass()).append(":").append(e.getMessage()).append("\n"); for( StackTraceElement s : list ) { b.append(s.toString()).append("\n"); } return b.toString(); } }