001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.replication.protocol; 028 import org.opends.messages.Message; 029 030 import static org.opends.server.loggers.debug.DebugLogger.debugEnabled; 031 import static org.opends.server.loggers.debug.DebugLogger.getTracer; 032 033 import java.io.Serializable; 034 import java.io.UnsupportedEncodingException; 035 import java.util.zip.DataFormatException; 036 037 import org.opends.server.loggers.debug.DebugTracer; 038 039 /** 040 * This message is part of the replication protocol. 041 * This message is sent by a server or a replication server when an error 042 * is detected in the context of a total update. 043 */ 044 public class ErrorMessage extends RoutableMessage implements 045 Serializable 046 { 047 private static final long serialVersionUID = 2726389860247088266L; 048 049 // The tracer object for the debug logger 050 private static final DebugTracer TRACER = getTracer(); 051 052 // Specifies the messageID built from the error that was detected 053 private int msgID; 054 055 // Specifies the complementary details about the error that was detected 056 private Message details = null; 057 058 /** 059 * Creates an ErrorMessage providing the destination server. 060 * 061 * @param sender The server ID of the server that send this message. 062 * @param destination The destination server or servers of this message. 063 * @param details The message containing the details of the error. 064 */ 065 public ErrorMessage(short sender, short destination, 066 Message details) 067 { 068 super(sender, destination); 069 this.msgID = details.getDescriptor().getId(); 070 this.details = details; 071 072 if (debugEnabled()) 073 TRACER.debugInfo(" Creating error message" + this.toString()); 074 } 075 076 /** 077 * Creates an ErrorMessage. 078 * 079 * @param destination replication server id 080 * @param details details of the error 081 */ 082 public ErrorMessage(short destination, Message details) 083 { 084 super((short)-2, destination); 085 this.msgID = details.getDescriptor().getId(); 086 this.details = details; 087 088 if (debugEnabled()) 089 TRACER.debugInfo(this.toString()); 090 } 091 092 /** 093 * Creates a new ErrorMessage by decoding the provided byte array. 094 * 095 * @param in A byte array containing the encoded information for the Message 096 * @throws DataFormatException If the in does not contain a properly 097 * encoded message. 098 */ 099 public ErrorMessage(byte[] in) throws DataFormatException 100 { 101 super(); 102 try 103 { 104 /* first byte is the type */ 105 if (in[0] != MSG_TYPE_ERROR) 106 throw new DataFormatException("input is not a valid InitializeMessage"); 107 int pos = 1; 108 109 // sender 110 int length = getNextLength(in, pos); 111 String senderString = new String(in, pos, length, "UTF-8"); 112 senderID = Short.valueOf(senderString); 113 pos += length +1; 114 115 // destination 116 length = getNextLength(in, pos); 117 String serverIdString = new String(in, pos, length, "UTF-8"); 118 destination = Short.valueOf(serverIdString); 119 pos += length +1; 120 121 // MsgID 122 length = getNextLength(in, pos); 123 String msgIdString = new String(in, pos, length, "UTF-8"); 124 msgID = Integer.valueOf(msgIdString); 125 pos += length +1; 126 127 // Details 128 length = getNextLength(in, pos); 129 details = Message.raw(new String(in, pos, length, "UTF-8")); 130 pos += length +1; 131 132 } 133 catch (UnsupportedEncodingException e) 134 { 135 throw new DataFormatException("UTF-8 is not supported by this jvm."); 136 } 137 } 138 139 /** 140 * Get the base DN from this InitializeMessage. 141 * 142 * @return the base DN from this InitializeMessage. 143 */ 144 public Message getDetails() 145 { 146 return details; 147 } 148 149 /** 150 * Get the base DN from this InitializeMessage. 151 * 152 * @return the base DN from this InitializeMessage. 153 */ 154 public int getMsgID() 155 { 156 return msgID; 157 } 158 159 /** 160 * {@inheritDoc} 161 */ 162 @Override 163 public byte[] getBytes() 164 { 165 /* The InitializeMessage is stored in the form : 166 * <operation type><basedn><serverid> 167 */ 168 try { 169 byte[] byteSender = String.valueOf(senderID).getBytes("UTF-8"); 170 byte[] byteDestination = String.valueOf(destination).getBytes("UTF-8"); 171 byte[] byteErrMsgId = String.valueOf(msgID).getBytes("UTF-8"); 172 byte[] byteDetails = details.toString().getBytes("UTF-8"); 173 174 int length = 1 + byteSender.length + 1 175 + byteDestination.length + 1 176 + byteErrMsgId.length + 1 177 + byteDetails.length + 1; 178 179 byte[] resultByteArray = new byte[length]; 180 181 // put the type of the operation 182 resultByteArray[0] = MSG_TYPE_ERROR; 183 int pos = 1; 184 185 // sender 186 pos = addByteArray(byteSender, resultByteArray, pos); 187 188 // destination 189 pos = addByteArray(byteDestination, resultByteArray, pos); 190 191 // MsgId 192 pos = addByteArray(byteErrMsgId, resultByteArray, pos); 193 194 // details 195 pos = addByteArray(byteDetails, resultByteArray, pos); 196 197 return resultByteArray; 198 } 199 catch (UnsupportedEncodingException e) 200 { 201 return null; 202 } 203 } 204 205 /** 206 * Returns a string representation of the message. 207 * 208 * @return the string representation of this message. 209 */ 210 public String toString() 211 { 212 return "ErrorMessage=["+ 213 " sender=" + this.senderID + 214 " destination=" + this.destination + 215 " msgID=" + this.msgID + 216 " details=" + this.details + "]"; 217 } 218 }