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.exception.RemoteRuntimeException; 025import org.apache.reef.wake.remote.impl.ObjectSerializableCodec; 026 027import java.util.logging.Level; 028import java.util.logging.Logger; 029 030/** 031 * Error message that REEF Client gets when there is an error in REEF resourcemanager. 032 */ 033public final class FailedRuntime extends AbstractFailure { 034 035 /** 036 * Standard java logger. 037 */ 038 private static final Logger LOG = Logger.getLogger(AbstractFailure.class.getName()); 039 040 /** 041 * Codec to decode serialized exception from a byte array. It is used in getThrowable(). 042 */ 043 private static final ObjectSerializableCodec<Exception> CODEC = new ObjectSerializableCodec<>(); 044 045 /** 046 * Create a new Failure object out of protobuf data. 047 * 048 * @param error Error message as a protocol buffers object. 049 */ 050 public FailedRuntime(final RuntimeErrorProto error) { 051 super(error.getIdentifier(), error.getMessage(), Optional.<String>empty(), Optional.of(getThrowable(error)), 052 Optional.<byte[]>empty()); 053 } 054 055 /** 056 * Retrieve Java exception from protobuf object, if possible. Otherwise, return null. 057 * This is a utility method used in the FailedRuntime constructor. 058 * 059 * @param error protobuf error message structure. 060 * @return Java exception or null if exception is missing or cannot be decoded. 061 */ 062 private static Throwable getThrowable(final RuntimeErrorProto error) { 063 final byte[] data = getData(error); 064 if (data != null) { 065 try { 066 return CODEC.decode(data); 067 } catch (final RemoteRuntimeException ex) { 068 LOG.log(Level.FINE, "Could not decode exception {0}: {1}", new Object[]{error, ex}); 069 } 070 } 071 return null; 072 } 073 074 /** 075 * Get binary data for the exception, if it exists. Otherwise, return null. 076 * This is a utility method used in the FailedRuntime constructor and getThrowable() method. 077 * 078 * @param error protobuf error message structure. 079 * @return byte array of the exception or null if exception is missing. 080 */ 081 private static byte[] getData(final RuntimeErrorProto error) { 082 return error.hasException() ? error.getException().toByteArray() : null; 083 } 084}