/*
* Licensed 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 com.addthis.hydra.meshy.http;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.util.Collection;
import java.util.function.Function;
import java.util.zip.GZIPInputStream;
import com.addthis.meshy.service.file.FileReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MeshHandler extends AbstractHandler {
Logger log = LoggerFactory.getLogger(MeshHandler.class);
MeshConnection connection;
ObjectMapper mapper;
public MeshHandler(MeshConnection connection) {
this.connection = connection;
this.mapper = new ObjectMapper();
}
@Override public void handle(
String s, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
switch (request.getPathInfo()) {
case "/get":
response.setStatus(HttpServletResponse.SC_OK);
response.setContentType("text/plain");
doGet(request.getParameter("uuid"), request.getParameter("path"), response.getOutputStream());
break;
case "/list":
response.setStatus(HttpServletResponse.SC_OK);
response.setContentType("application/json");
doList(request.getParameter("path"), response.getOutputStream());
break;
case "/check-binary":
response.setStatus(HttpServletResponse.SC_OK);
response.setContentType("application/json");
doCheckBinary(request.getParameter("uuid"), request.getParameter("path"), response.getOutputStream());
default:
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
response.getWriter().print("Use /get, /list, or /check-binary");
}
baseRequest.setHandled(true);
}
private void doGet(String uuid, String path, OutputStream outputStream) {
try (OutputStream o = outputStream) {
connection.streamFile(uuid, path, o, MeshHandler.getTransformer(path));
} catch (IOException e) {
log.error("Error while streaming file", e);
}
}
private void doList(String path, OutputStream outputStream) {
Collection<FileReference> files = connection.list(path);
try (OutputStream o = outputStream) {
mapper.writeValue(o, files);
} catch (IOException e) {
log.error("Failed to write file list to http output", e);
}
}
private void doCheckBinary(String uuid, String path, OutputStream outputStream) {
try (OutputStream o = outputStream) {
boolean binary = connection.mightBeBinaryFile(uuid, path, MeshHandler.getTransformer(path));
// wrap and write the value
mapper.writeValue(outputStream, new Binary(binary));
} catch (IOException e) {
log.error("Error writing binary status to http output", e);
}
}
private static Function<InputStream, ? extends InputStream> getTransformer(String path) {
if (path.endsWith(".gz")) {
return in -> {
try {
return new GZIPInputStream(in);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
};
}
return Function.identity();
}
private static class Binary {
public boolean binary;
public Binary(boolean binary) {
this.binary = binary;
}
}
}