Java tutorial
/* * Copyright 2012 The Athena Project * * The Athena Project licenses this file to you licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.athena.sqs; import java.io.IOException; import java.util.Arrays; import java.util.concurrent.ConcurrentHashMap; import org.codehaus.jackson.JsonParseException; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.type.TypeReference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import sun.misc.BASE64Decoder; /** * This class allows you to process a composite message by splitting it up, * and the re-aggregating the responses back into a single message. * * @author Ji-Woong Choi(ienvyou@gmail.com) * */ @Service public class MessageAggregator { private final Logger logger = LoggerFactory.getLogger(getClass()); // Store transaction id and message map private static ConcurrentHashMap<String, ConcurrentHashMap<Integer, String>> txMap = new ConcurrentHashMap<String, ConcurrentHashMap<Integer, String>>(); /** * Aggregate splitted messages into single message. * @param rawData base64 string * @throws MessageException */ public void aggregate(String rawString) throws MessageException { try { BASE64Decoder decoder = new BASE64Decoder(); int index = rawString.indexOf(MessageContext.DATA_DELIMITER); // 1. Split header String[] header = parseHeader(rawString.substring(0, index)); String content = rawString.substring(index + 2); // 2. Assign header value to local variable MessageTransferType transferType = MessageTransferType.valueOf(header[0]); String businessName = header[1]; String transactionId = header[2]; MessageSplitType splitType = MessageSplitType.valueOf(header[3]); int current = Integer.parseInt(header[4]); int total = Integer.parseInt(header[5]); // 3 Check Message Single switch (splitType) { case SINGLE: // TODO single message work doProcess(transactionId, new String(decoder.decodeBuffer(content))); return; case MULTI: break; } logger.debug("Transaction ID : " + transactionId); // 4. Check Message Order // If transaction id is not exist in txMap, create new tx map object if (!txMap.containsKey(transactionId)) { ConcurrentHashMap<Integer, String> orderedMessages = new ConcurrentHashMap<Integer, String>(); orderedMessages.put(current, content); txMap.put(transactionId, orderedMessages); } else { // Already same transaction message was inserted ConcurrentHashMap<Integer, String> orderedMessages = txMap.get(transactionId); orderedMessages.put(current, content); // Message compare if (orderedMessages.size() == total) { // All messages arrived Object[] key = orderedMessages.keySet().toArray(); Arrays.sort(key); String finalMessage = ""; for (int i = 0; i < key.length; i++) { finalMessage += orderedMessages.get(key[i]); } logger.debug("===== [ " + transactionId + "] ======"); logger.debug(new String(decoder.decodeBuffer(finalMessage))); boolean isDelete = txMap.remove(transactionId, orderedMessages); if (!isDelete) { throw new MessageException("Can't delete message from transaction map"); } doProcess(transactionId, new String(decoder.decodeBuffer(finalMessage))); } } } catch (Exception e) { e.printStackTrace(); } } private String[] parseHeader(String header) { return header.split("\\|"); } /** * Process single message type. * @param message * @throws IOException * @throws JsonMappingException * @throws JsonParseException */ public void doProcess(String transactionId, String rawString) throws MessageException { try { ObjectMapper mapper = new ObjectMapper(); Message message = mapper.readValue(rawString, new TypeReference<Message>() { }); logger.debug("=======================[MESSAGES]============================="); logger.debug(message.toString()); logger.debug("==========================================================="); } catch (Exception e) { throw new MessageException("Error during processing message: " + e.getMessage()); } finally { } } }