package net.decix.jipfix.header; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import net.decix.util.HeaderBytesException; import net.decix.util.HeaderParseException; import net.decix.util.Utility; /** * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Version Number | Length | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Export Time | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Sequence Number | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Observation Domain ID | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * @author tking * */ public class MessageHeader extends AbstractHeader implements IPFIXEntity { private final static Logger LOGGER = Logger.getLogger(SetHeader.class.getName()); private final static int HEADERLENGTH = 16; private int versionNumber; private Date exportTime; private long sequenceNumber; private long observationDomainID; private List<SetHeader> setHeaders = new ArrayList<SetHeader>(); public int getVersionNumber() { return versionNumber; } public void setVersionNumber(int versionNumber) { this.versionNumber = versionNumber; } public Date getExportTime() { return exportTime; } public void setExportTime(Date exportTime) { this.exportTime = exportTime; } public long getSequenceNumber() { return sequenceNumber; } public void setSequenceNumber(long sequenceNumber) { this.sequenceNumber = sequenceNumber; } public long getObservationDomainID() { return observationDomainID; } public void setObservationDomainID(long observationDomainID) { this.observationDomainID = observationDomainID; } public List<SetHeader> getSetHeaders() { return setHeaders; } public void setSetHeaders(List<SetHeader> setHeaders) { this.setHeaders = setHeaders; int length = 0; for (SetHeader header : setHeaders) { length += header.getLength(); } setLength(length + HEADERLENGTH); } public static MessageHeader parse(byte[] data) throws HeaderParseException { try { if (data.length < 16) throw new HeaderParseException("Data array too short."); MessageHeader mh = new MessageHeader(); // version number byte[] versionNumber = new byte[2]; System.arraycopy(data, 0, versionNumber, 0, 2); mh.setVersionNumber(Utility.twoBytesToInteger(versionNumber)); // length byte[] length = new byte[2]; System.arraycopy(data, 2, length, 0, 2); mh.setLength(Utility.twoBytesToInteger(length)); // export time byte[] exportTime = new byte[4]; System.arraycopy(data, 4, exportTime, 0, 4); long secondsSinceEpoche = Utility.fourBytesToLong(exportTime); long milliSecondsSinceEpoche = secondsSinceEpoche * 1000; mh.setExportTime(new Date(milliSecondsSinceEpoche)); // sequence number byte[] sequenceNumber = new byte[4]; System.arraycopy(data, 8, sequenceNumber, 0, 4); mh.setSequenceNumber(Utility.fourBytesToLong(sequenceNumber)); // observation domain id byte[] observationDomainID = new byte[4]; System.arraycopy(data, 12, observationDomainID, 0, 4); mh.setObservationDomainID(Utility.fourBytesToLong(observationDomainID)); // set header int offset = 16; while ((mh.getLength() - offset) > 0) { byte[] subData = new byte[mh.getLength() - offset]; System.arraycopy(data, offset, subData, 0, subData.length); SetHeader sh = SetHeader.parse(subData); mh.getSetHeaders().add(sh); offset += sh.getLength(); } if ((mh.getLength() - offset) != 0) LOGGER.log(Level.INFO, "Unused bytes: " + (mh.getLength() - offset)); return mh; } catch (Exception e) { throw new HeaderParseException("Parse error: " + e.getMessage()); } } public byte[] getBytes() throws HeaderBytesException { try { byte[] data = new byte[length]; // version number System.arraycopy(Utility.integerToTwoBytes(versionNumber), 0, data, 0, 2); // length System.arraycopy(Utility.integerToTwoBytes(length), 0, data, 2, 2); // export time System.arraycopy(Utility.longToFourBytes(exportTime.getTime() / 1000), 0, data, 4, 4); // sequence number System.arraycopy(Utility.longToFourBytes(sequenceNumber), 0, data, 8, 4); // observation domain id System.arraycopy(Utility.longToFourBytes(observationDomainID), 0, data, 12, 4); // set header int offset = 16; for (SetHeader sh : setHeaders) { byte[] temp = sh.getBytes(); System.arraycopy(temp, 0, data, offset, sh.getLength()); offset += sh.getLength(); } return data; } catch (Exception e) { e.printStackTrace(); throw new HeaderBytesException("Error while generating the bytes: " + e.getMessage()); } } public String toString() { StringBuilder sb = new StringBuilder(); sb.append("[MessageHeader]: "); sb.append("Version Number: "); sb.append(versionNumber); sb.append(", "); sb.append("Length: "); sb.append(length); sb.append(", "); sb.append("Export time: "); sb.append(exportTime); sb.append(", "); sb.append("Sequence number: "); sb.append(sequenceNumber); sb.append(", "); sb.append("Observation Domain ID: "); sb.append(observationDomainID); sb.append(", "); sb.append("SetHeaders: "); sb.append(setHeaders.size()); sb.append(", "); for (SetHeader sh : setHeaders) { sb.append(sh); sb.append(", "); } return sb.toString(); } }