001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.reef.client; 020 021import org.apache.reef.common.AbstractFailure; 022import org.apache.reef.proto.ReefServiceProtos.RuntimeErrorProto; 023import org.apache.reef.util.Optional; 024import org.apache.reef.wake.remote.impl.ObjectSerializableCodec; 025 026import java.util.logging.Level; 027import java.util.logging.Logger; 028 029/** 030 * Error message that REEF Client gets when there is an error in REEF resourcemanager. 031 */ 032public final class FailedRuntime extends AbstractFailure { 033 034 /** 035 * Standard java logger. 036 */ 037 private static final Logger LOG = Logger.getLogger(AbstractFailure.class.getName()); 038 039 /** 040 * Codec to decode serialized exception from a byte array. It is used in getThrowable(). 041 */ 042 private static final ObjectSerializableCodec<Exception> CODEC = new ObjectSerializableCodec<>(); 043 044 /** 045 * Create a new Failure object out of protobuf data. 046 * 047 * @param error Error message as a protocol buffers object. 048 */ 049 public FailedRuntime(final RuntimeErrorProto error) { 050 super(error.getIdentifier(), error.getMessage(), Optional.<String>empty(), Optional.of(getThrowable(error)), Optional.<byte[]>empty()); 051 } 052 053 /** 054 * Retrieve Java exception from protobuf object, if possible. Otherwise, return null. 055 * This is a utility method used in the FailedRuntime constructor. 056 * 057 * @param error protobuf error message structure. 058 * @return Java exception or null if exception is missing or cannot be decoded. 059 */ 060 private static Throwable getThrowable(final RuntimeErrorProto error) { 061 final byte[] data = getData(error); 062 if (data != null) { 063 try { 064 return CODEC.decode(data); 065 } catch (final Throwable ex) { 066 LOG.log(Level.FINE, "Could not decode exception {0}: {1}", new Object[]{error, ex}); 067 } 068 } 069 return null; 070 } 071 072 /** 073 * Get binary data for the exception, if it exists. Otherwise, return null. 074 * This is a utility method used in the FailedRuntime constructor and getThrowable() method. 075 * 076 * @param error protobuf error message structure. 077 * @return byte array of the exception or null if exception is missing. 078 */ 079 private static byte[] getData(final RuntimeErrorProto error) { 080 return error.hasException() ? error.getException().toByteArray() : null; 081 } 082}