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 2014 ForgeRock AS. 015 */ 016package org.opends.server.replication.protocol; 017 018import java.util.zip.DataFormatException; 019 020import org.opends.server.replication.common.CSN; 021 022import static org.opends.server.replication.protocol.ByteArrayBuilder.*; 023 024/** 025 * Class that define messages sent by a replica (DS) to the replication server 026 * (RS) to let the RS know the date at which a replica went offline. 027 */ 028public class ReplicaOfflineMsg extends UpdateMsg 029{ 030 031 /** 032 * Constructor of a replica offline message providing the offline timestamp in 033 * a CSN. 034 * 035 * @param offlineCSN 036 * the provided offline CSN 037 */ 038 public ReplicaOfflineMsg(final CSN offlineCSN) 039 { 040 super(offlineCSN, new byte[0]); 041 } 042 043 /** 044 * Creates a message by deserializing it from the provided byte array. 045 * 046 * @param in 047 * The provided byte array. 048 * @throws DataFormatException 049 * When an error occurs during decoding . 050 */ 051 public ReplicaOfflineMsg(byte[] in) throws DataFormatException 052 { 053 try 054 { 055 final ByteArrayScanner scanner = new ByteArrayScanner(in); 056 final byte msgType = scanner.nextByte(); 057 if (msgType != MSG_TYPE_REPLICA_OFFLINE) 058 { 059 throw new DataFormatException("input is not a valid " 060 + getClass().getSimpleName() + " message: " + msgType); 061 } 062 protocolVersion = scanner.nextShort(); 063 csn = scanner.nextCSN(); 064 065 if (!scanner.isEmpty()) 066 { 067 throw new DataFormatException( 068 "Did not expect to find more bytes to read for " 069 + getClass().getSimpleName()); 070 } 071 } 072 catch (RuntimeException e) 073 { 074 // Index out of bounds, bad format, etc. 075 throw new DataFormatException("byte[] is not a valid " 076 + getClass().getSimpleName()); 077 } 078 } 079 080 /** {@inheritDoc} */ 081 @Override 082 public byte[] getBytes(short protocolVersion) 083 { 084 if (protocolVersion < ProtocolVersion.REPLICATION_PROTOCOL_V8) 085 { 086 return null; 087 } 088 final ByteArrayBuilder builder = new ByteArrayBuilder(size()); 089 builder.appendByte(MSG_TYPE_REPLICA_OFFLINE); 090 builder.appendShort(protocolVersion); 091 builder.appendCSN(csn); 092 return builder.toByteArray(); 093 } 094 095 /** {@inheritDoc} */ 096 @Override 097 public int size() 098 { 099 return bytes(1) + shorts(1) + csns(1); 100 } 101 102 /** {@inheritDoc} */ 103 @Override 104 public boolean contributesToDomainState() 105 { 106 return false; // replica offline msg MUST NOT update the ds-sync-state 107 } 108 109 /** {@inheritDoc} */ 110 @Override 111 public String toString() 112 { 113 return getClass().getSimpleName() + " offlineCSN=" + csn; 114 } 115}