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, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.rest; 019 020import java.io.IOException; 021import java.io.InputStream; 022import java.io.OutputStream; 023import org.apache.yetus.audience.InterfaceAudience; 024 025import org.apache.hbase.thirdparty.com.google.protobuf.CodedInputStream; 026import org.apache.hbase.thirdparty.com.google.protobuf.CodedOutputStream; 027import org.apache.hbase.thirdparty.com.google.protobuf.Message; 028 029/** 030 * Common interface for models capable of supporting protobuf marshalling and unmarshalling. Hooks 031 * up to the ProtobufMessageBodyConsumer and ProtobufMessageBodyProducer adapters. 032 */ 033@InterfaceAudience.Private 034public interface ProtobufMessageHandler { 035 036 // The Jetty 9.4 HttpOutput default commit size is 32K/4 = 8K. We use that size to avoid 037 // double buffering (and copying) in HttpOutput. If we ever increase the HttpOutput commit size, 038 // we need to adjust this accordingly. We should also revisit this when Jetty is upgraded. 039 int BUFFER_SIZE = 8 * 1024; 040 041 /** Writes the protobuf represention of the model to os */ 042 default void writeProtobufOutput(OutputStream os) throws IOException { 043 // Creating an explicit CodedOutputStream for the following reasons : 044 // 1. This avoids the cost of pre-computing the message size 045 // 2. This lets us set the buffer size explicitly 046 CodedOutputStream cos = CodedOutputStream.newInstance(os, BUFFER_SIZE); 047 messageFromObject().writeTo(cos); 048 cos.flush(); 049 } 050 051 /** 052 * Returns the protobuf represention of the model in a byte array. Use 053 * {@link org.apache.hadoop.hbase.rest.ProtobufMessageHandler#writeProtobufOutput(OutputStream)} 054 * for better performance 055 * @return the protobuf encoded object in a byte array 056 */ 057 default byte[] createProtobufOutput() { 058 return messageFromObject().toByteArray(); 059 } 060 061 /** 062 * Convert to model to a protobuf Message object 063 * @return the protobuf Message object 064 */ 065 Message messageFromObject(); 066 067 /** 068 * Initialize the model from a protobuf representation. Use 069 * {@link org.apache.hadoop.hbase.rest.ProtobufMessageHandler#getObjectFromMessage(InputStream)} 070 * for better performance 071 * @param message the raw bytes of the protobuf message 072 * @return reference to self for convenience 073 */ 074 default ProtobufMessageHandler getObjectFromMessage(byte[] message) throws IOException { 075 final CodedInputStream codedInput = CodedInputStream.newInstance(message); 076 codedInput.setSizeLimit(message.length); 077 return getObjectFromMessage(codedInput); 078 } 079 080 /** 081 * Initialize the model from a protobuf representation. 082 * @param is InputStream providing the protobuf message 083 * @return reference to self for convenience 084 */ 085 default ProtobufMessageHandler getObjectFromMessage(InputStream is) throws IOException { 086 final CodedInputStream codedInput = CodedInputStream.newInstance(is); 087 codedInput.setSizeLimit(Integer.MAX_VALUE); 088 return getObjectFromMessage(codedInput); 089 } 090 091 ProtobufMessageHandler getObjectFromMessage(CodedInputStream cis) throws IOException; 092}