/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.giraph.debugger.utils; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.apache.giraph.debugger.Integrity.MessageIntegrityViolation; import org.apache.giraph.debugger.Integrity.MessageIntegrityViolation.ExtendedOutgoingMessage; import org.apache.hadoop.io.Writable; import org.apache.hadoop.io.WritableComparable; import com.google.protobuf.GeneratedMessage; /** * A wrapper class around the contents of MessageIntegrityViolation inside * integrity.proto. In scenario.proto most things are stored as serialized byte * arrays and this class gives them access through the java classes that those * byte arrays serialize. * * @param <I> * vertex ID class. * @param <M2> * outgoing message class. * * author Semih Salihoglu */ @SuppressWarnings("rawtypes") public class MsgIntegrityViolationWrapper<I extends WritableComparable, M2 extends Writable> extends BaseScenarioAndIntegrityWrapper<I> { /** * Outgoing message class. */ private Class<M2> outgoingMessageClass; /** * List of captured outgoing messages. */ private final List<ExtendedOutgoingMessageWrapper> extendedOutgoingMessageWrappers = new ArrayList<>(); /** * The superstep number at which these message violations were found. */ private long superstepNo; /** * Empty constructor to be used for loading from HDFS. */ public MsgIntegrityViolationWrapper() { } /** * Constructor with field values. * * @param vertexIdClass Vertex id class. * @param outgoingMessageClass Outgoing message class. */ public MsgIntegrityViolationWrapper(Class<I> vertexIdClass, Class<M2> outgoingMessageClass) { initialize(vertexIdClass, outgoingMessageClass); } /** * Initializes this instance. * * @param vertexIdClass Vertex id class. * @param outgoingMessageClass Outgoing message class. */ private void initialize(Class<I> vertexIdClass, Class<M2> outgoingMessageClass) { super.initialize(vertexIdClass); this.outgoingMessageClass = outgoingMessageClass; } public Collection<ExtendedOutgoingMessageWrapper> getExtendedOutgoingMessageWrappers() { return extendedOutgoingMessageWrappers; } /** * Captures an outgoing message. * * @param srcId Sending vertex id. * @param destinationId Receiving vertex id. * @param message The message being sent to capture. */ public void addMsgWrapper(I srcId, I destinationId, M2 message) { extendedOutgoingMessageWrappers.add(new ExtendedOutgoingMessageWrapper( DebuggerUtils.makeCloneOf(srcId, vertexIdClass), DebuggerUtils .makeCloneOf(destinationId, vertexIdClass), DebuggerUtils.makeCloneOf( message, outgoingMessageClass))); } /** * @return The number of captured messages so far. */ public int numMsgWrappers() { return extendedOutgoingMessageWrappers.size(); } public Class<M2> getOutgoingMessageClass() { return outgoingMessageClass; } @Override public String toString() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(super.toString()); stringBuilder.append("\noutgoingMessageClass: " + getOutgoingMessageClass().getCanonicalName()); for (ExtendedOutgoingMessageWrapper extendedOutgoingMessageWrapper : getExtendedOutgoingMessageWrappers()) { stringBuilder.append("\n" + extendedOutgoingMessageWrapper); } return stringBuilder.toString(); } /** * Class for capturing outgoing messages as well as the sending vertex id. */ public class ExtendedOutgoingMessageWrapper extends BaseWrapper { /** * Sending vertex id. */ private I srcId; /** * Receiving vertex id. */ private I destinationId; /** * Message being sent. */ private M2 message; /** * Constructor with field values. * * @param srcId Sending vertex id. * @param destinationId Receiving vertex id. * @param message Message being sent. */ public ExtendedOutgoingMessageWrapper(I srcId, I destinationId, M2 message) { this.setSrcId(srcId); this.setDestinationId(destinationId); this.setMessage(message); } /** * Default constructor. */ public ExtendedOutgoingMessageWrapper() { } @Override public String toString() { return "extendedOutgoingMessage: srcId: " + getSrcId() + " destinationId: " + getDestinationId() + " message: " + getMessage(); } @Override public GeneratedMessage buildProtoObject() { ExtendedOutgoingMessage.Builder extendedOutgoingMessageBuilder = ExtendedOutgoingMessage.newBuilder(); extendedOutgoingMessageBuilder.setSrcId(toByteString(getSrcId())); extendedOutgoingMessageBuilder .setDestinationId(toByteString(getDestinationId())); extendedOutgoingMessageBuilder.setMsgData(toByteString(getMessage())); return extendedOutgoingMessageBuilder.build(); } @Override public GeneratedMessage parseProtoFromInputStream(InputStream inputStream) throws IOException { return ExtendedOutgoingMessage.parseFrom(inputStream); } @Override public void loadFromProto(GeneratedMessage generatedMessage) throws ClassNotFoundException, IOException, InstantiationException, IllegalAccessException { ExtendedOutgoingMessage extendedOutgoingMessage = (ExtendedOutgoingMessage) generatedMessage; this.setSrcId(DebuggerUtils.newInstance(vertexIdClass)); fromByteString(extendedOutgoingMessage.getSrcId(), this.getSrcId()); this.setDestinationId(DebuggerUtils.newInstance(vertexIdClass)); fromByteString(extendedOutgoingMessage.getDestinationId(), this.getDestinationId()); this.setMessage(DebuggerUtils.newInstance(outgoingMessageClass)); fromByteString(extendedOutgoingMessage.getMsgData(), this.getMessage()); } /** * @return the srcId */ public I getSrcId() { return srcId; } /** * @param srcId the srcId to set */ public void setSrcId(I srcId) { this.srcId = srcId; } /** * @return the destinationId */ public I getDestinationId() { return destinationId; } /** * @param destinationId the destinationId to set */ public void setDestinationId(I destinationId) { this.destinationId = destinationId; } /** * @return the message */ public M2 getMessage() { return message; } /** * @param message the message to set */ public void setMessage(M2 message) { this.message = message; } } public long getSuperstepNo() { return superstepNo; } public void setSuperstepNo(long superstepNo) { this.superstepNo = superstepNo; } @Override public GeneratedMessage buildProtoObject() { MessageIntegrityViolation.Builder messageIntegrityViolationBuilder = MessageIntegrityViolation.newBuilder(); messageIntegrityViolationBuilder.setVertexIdClass(getVertexIdClass() .getName()); messageIntegrityViolationBuilder .setOutgoingMessageClass(getOutgoingMessageClass().getName()); messageIntegrityViolationBuilder.setSuperstepNo(getSuperstepNo()); for (ExtendedOutgoingMessageWrapper extendedOutgoingMessageWrapper : extendedOutgoingMessageWrappers) { messageIntegrityViolationBuilder .addMessage((ExtendedOutgoingMessage) extendedOutgoingMessageWrapper .buildProtoObject()); } return messageIntegrityViolationBuilder.build(); } @Override @SuppressWarnings("unchecked") public void loadFromProto(GeneratedMessage generatedMessage) throws ClassNotFoundException, IOException, InstantiationException, IllegalAccessException { MessageIntegrityViolation msgIntegrityViolation = (MessageIntegrityViolation) generatedMessage; Class<I> vertexIdClass = (Class<I>) castClassToUpperBound( Class.forName(msgIntegrityViolation.getVertexIdClass()), WritableComparable.class); Class<M2> outgoingMessageClazz = (Class<M2>) castClassToUpperBound( Class.forName(msgIntegrityViolation.getOutgoingMessageClass()), Writable.class); initialize(vertexIdClass, outgoingMessageClazz); setSuperstepNo(msgIntegrityViolation.getSuperstepNo()); for (ExtendedOutgoingMessage extendOutgoingMessage : msgIntegrityViolation .getMessageList()) { ExtendedOutgoingMessageWrapper extendedOutgoingMessageWrapper = new ExtendedOutgoingMessageWrapper(); extendedOutgoingMessageWrapper.loadFromProto(extendOutgoingMessage); extendedOutgoingMessageWrappers.add(extendedOutgoingMessageWrapper); } } @Override public GeneratedMessage parseProtoFromInputStream(InputStream inputStream) throws IOException { return MessageIntegrityViolation.parseFrom(inputStream); } }