001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2006-2010 Sun Microsystems, Inc.
015 * Portions Copyright 2013-2015 ForgeRock AS.
016 */
017package org.opends.server.replication.protocol;
018
019import java.util.zip.DataFormatException;
020
021/**
022 * This message is part of the replication protocol.
023 * This message is sent by a server to one or several other servers and
024 * contain one entry to be sent over the protocol in the context of
025 * an import/export over the protocol.
026 */
027public class EntryMsg extends RoutableMsg
028{
029  /** The byte array containing the bytes of the entry transported. */
030  private final byte[] entryByteArray;
031  /** From V4. */
032  private int msgId = -1;
033
034  /**
035   * Creates a new EntryMsg.
036   *
037   * @param serverID      The sender of this message.
038   * @param destination The destination of this message.
039   * @param entryBytes  The bytes of the entry.
040   * @param msgId       Message counter.
041   */
042  public EntryMsg(int serverID, int destination, byte[] entryBytes, int msgId)
043  {
044    this(serverID, destination, entryBytes, 0, entryBytes.length, msgId);
045  }
046
047  /**
048   * Creates a new EntryMsg.
049   *
050   * @param serverID    The sender of this message.
051   * @param destination The destination of this message.
052   * @param entryBytes  The bytes of the entry.
053   * @param startPos    The starting Position in the array.
054   * @param length      Number of array elements to be copied.
055   * @param msgId       Message counter.
056   */
057  public EntryMsg(int serverID, int destination, byte[] entryBytes, int startPos,
058      int length, int msgId)
059  {
060    super(serverID, destination);
061    this.entryByteArray = new byte[length];
062    System.arraycopy(entryBytes, startPos, this.entryByteArray, 0, length);
063    this.msgId = msgId;
064  }
065
066  /**
067   * Creates a new EntryMsg from its encoded form.
068   *
069   * @param in The byte array containing the encoded form of the message.
070   * @param version The protocol version to use to decode the msg
071   * @throws DataFormatException If the byte array does not contain a valid
072   *                             encoded form of the ServerStartMessage.
073   */
074  EntryMsg(byte[] in, short version) throws DataFormatException
075  {
076    final ByteArrayScanner scanner = new ByteArrayScanner(in);
077    final byte msgType = scanner.nextByte();
078    if (msgType != MSG_TYPE_ENTRY)
079    {
080      throw new DataFormatException("input is not a valid "
081          + getClass().getCanonicalName());
082    }
083    this.senderID = scanner.nextIntUTF8();
084    this.destination = scanner.nextIntUTF8();
085    if (version >= ProtocolVersion.REPLICATION_PROTOCOL_V4)
086    {
087      this.msgId = scanner.nextIntUTF8();
088    }
089    this.entryByteArray = scanner.remainingBytesZeroTerminated();
090  }
091
092  /**
093   * Returns the entry bytes.
094   * @return The entry bytes.
095   */
096  public byte[] getEntryBytes()
097  {
098    return entryByteArray;
099  }
100
101  /** {@inheritDoc} */
102  @Override
103  public byte[] getBytes(short version)
104  {
105    final ByteArrayBuilder builder = new ByteArrayBuilder();
106    builder.appendByte(MSG_TYPE_ENTRY);
107    builder.appendIntUTF8(senderID);
108    builder.appendIntUTF8(destination);
109    if (version >= ProtocolVersion.REPLICATION_PROTOCOL_V4)
110    {
111      builder.appendIntUTF8(msgId);
112    }
113    builder.appendZeroTerminatedByteArray(entryByteArray);
114    return builder.toByteArray();
115  }
116
117  /**
118   * Return the msg id.
119   * @return The msg id.
120   */
121  public int getMsgId()
122  {
123    return this.msgId;
124  }
125
126  /**
127   * Set the msg id.
128   * @param msgId The msg id.
129   */
130  public void setMsgId(int msgId)
131  {
132    this.msgId = msgId;
133  }
134}