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.webserver;
020
021import org.apache.avro.file.DataFileReader;
022import org.apache.avro.file.DataFileWriter;
023import org.apache.avro.io.*;
024import org.apache.avro.specific.SpecificDatumReader;
025import org.apache.avro.specific.SpecificDatumWriter;
026
027import javax.servlet.ServletException;
028import java.io.ByteArrayOutputStream;
029import java.io.File;
030import java.io.IOException;
031import java.nio.ByteBuffer;
032import java.util.*;
033
034/**
035 * Serialize Http Request Response data with Avro.
036 */
037public class AvroHttpSerializer {
038
039  public static final String JSON_CHARSET = "ISO-8859-1";
040
041  public AvroHttpSerializer() {
042  }
043
044  /**
045   * Convert from HttpServletRequest to AvroHttpRequest.
046   */
047  public AvroHttpRequest toAvro(final ParsedHttpRequest parsedRequest) throws ServletException, IOException {
048
049    return AvroHttpRequest.newBuilder()
050        .setRequestUrl(parsedRequest.getRequestUrl())
051        .setHttpMethod(parsedRequest.getMethod())
052        .setQueryString(parsedRequest.getQueryString())
053        .setPathInfo(parsedRequest.getPathInfo())
054        .setInputStream(ByteBuffer.wrap(parsedRequest.getInputStream()))
055        .setHeader(parsedRequest.getHeaderEntryList())
056        .build();
057  }
058
059  /**
060   * Convert AvroHttpRequest to JSON String.
061   */
062  public String toString(final AvroHttpRequest request) {
063    final DatumWriter<AvroHttpRequest> configurationWriter = new SpecificDatumWriter<>(AvroHttpRequest.class);
064    try (final ByteArrayOutputStream out = new ByteArrayOutputStream()) {
065      final JsonEncoder encoder = EncoderFactory.get().jsonEncoder(AvroHttpRequest.SCHEMA$, out);
066      configurationWriter.write(request, encoder);
067      encoder.flush();
068      return out.toString(JSON_CHARSET);
069    } catch (final IOException e) {
070      throw new RuntimeException(e);
071    }
072  }
073
074  /**
075   * Convert AvroHttpRequest to bytes.
076   */
077  public byte[] toBytes(final AvroHttpRequest request) {
078    final DatumWriter<AvroHttpRequest> requestWriter = new SpecificDatumWriter<>(AvroHttpRequest.class);
079    try (final ByteArrayOutputStream out = new ByteArrayOutputStream()) {
080      final BinaryEncoder encoder = EncoderFactory.get().binaryEncoder(out, null);
081      requestWriter.write(request, encoder);
082      encoder.flush();
083      return out.toByteArray();
084    } catch (final IOException e) {
085      throw new RuntimeException(e);
086    }
087  }
088
089  /**
090   * Conver AvroHttpRequest to a file.
091   * @param avroHttpRequest
092   * @param file
093   * @throws IOException
094   * @throws ServletException
095   */
096  public void toFile(final AvroHttpRequest avroHttpRequest, final File file) throws IOException, ServletException {
097    final DatumWriter<AvroHttpRequest> httpWriter = new SpecificDatumWriter<>(AvroHttpRequest.class);
098    try (final DataFileWriter<AvroHttpRequest> dataFileWriter = new DataFileWriter<>(httpWriter)) {
099      dataFileWriter.create(avroHttpRequest.getSchema(), file);
100      dataFileWriter.append(avroHttpRequest);
101    }
102  }
103
104  /**
105   * Convert a file to AvroHttpRequest.
106   * @param file
107   * @return
108   * @throws IOException
109   */
110  public AvroHttpRequest fromFile(final File file) throws IOException {
111    final AvroHttpRequest avrohttpRequest;
112    try (final DataFileReader<AvroHttpRequest> dataFileReader =
113                 new DataFileReader<>(file, new SpecificDatumReader<>(AvroHttpRequest.class))) {
114      avrohttpRequest = dataFileReader.next();
115    }
116    return avrohttpRequest;
117  }
118
119  /**
120   * Convert JSON String to AvroHttpRequest.
121   */
122  public AvroHttpRequest fromString(final String jasonStr) {
123    try {
124      final JsonDecoder decoder = DecoderFactory.get().jsonDecoder(AvroHttpRequest.getClassSchema(), jasonStr);
125      final SpecificDatumReader<AvroHttpRequest> reader = new SpecificDatumReader<>(AvroHttpRequest.class);
126      return reader.read(null, decoder);
127    } catch (final IOException e) {
128      throw new RuntimeException(e);
129    }
130  }
131
132  /**
133   * Convert bytes to AvroHttpRequest.
134   */
135  public AvroHttpRequest fromBytes(final byte[] theBytes) {
136    try {
137      final BinaryDecoder decoder = DecoderFactory.get().binaryDecoder(theBytes, null);
138      final SpecificDatumReader<AvroHttpRequest> reader = new SpecificDatumReader<>(AvroHttpRequest.class);
139      return reader.read(null, decoder);
140    } catch (final IOException e) {
141      throw new RuntimeException(e);
142    }
143  }
144}