blob: 6d0f6892a2f807277648150fb124eb79855d417e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.unomi.rest;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.opencsv.CSVWriter;
import org.apache.cxf.rs.security.cors.CrossOriginResourceSharing;
import org.apache.unomi.api.Profile;
import org.apache.unomi.api.services.ConfigSharingService;
import org.apache.unomi.api.services.ProfileService;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jws.WebService;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* A servlet filter to serve a context-specific Javascript containing the current request context object.
*/
@WebService
@CrossOriginResourceSharing(
allowAllOrigins = true,
allowCredentials = true
)
@Path("/")
@Component(service = ClientEndpoint.class, property = "osgi.jaxrs.resource=true")
public class ClientEndpoint {
private static final Logger logger = LoggerFactory.getLogger(ClientEndpoint.class.getName());
private static final String CONTENT_DISPOSITION_HEADER_KEY = "Content-Disposition";
private static final String FILE_NAME_WO_EXT = "my-profile";
private static String getContentDispostionHeader(String extension) {
return String.format("attachment; filename=\"%s.%s\"", FILE_NAME_WO_EXT, extension);
}
@Reference
private ProfileService profileService;
@Reference
private ConfigSharingService configSharingService;
@Context
HttpServletRequest request;
@Context
HttpServletResponse response;
@OPTIONS
@Path("/client/{operation}/{param}")
public Response options() {
return Response.status(Response.Status.NO_CONTENT).build();
}
@GET
@Path("/client/{operation}/{param}")
public Response getClient(@PathParam("operation") String operation, @PathParam("param") String param) throws JsonProcessingException {
if ("myprofile".equals(operation)) {
if (((String) configSharingService.getProperty("allowedProfileDownloadFormats")).contains(param)) {
return donwloadCurrentProfile(param);
} else {
throw new InternalServerErrorException(String.format("%s is not an allowed param", param));
}
}
throw new NotFoundException();
}
private Response donwloadCurrentProfile(String downloadFileType) throws JsonProcessingException {
String cookieProfileId = null;
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (configSharingService.getProperty("profileIdCookieName").equals(cookie.getName())) {
cookieProfileId = cookie.getValue();
}
}
}
if (cookieProfileId != null) {
Profile currentProfile = profileService.load(cookieProfileId);
if (currentProfile != null) {
switch (downloadFileType) {
case "yaml":
return prepareYamlFileToDownload(currentProfile, false);
case "json":
return prepareJsonFileToDownload(currentProfile);
case "csv":
return prepareCsvFileToDownload(currentProfile, request.getParameter("vertical") != null);
case "text":
return prepareYamlFileToDownload(currentProfile, true);
default:
throw new NotFoundException();
}
}
}
throw new NotFoundException();
}
private Response prepareCsvFileToDownload(Profile currentProfile, boolean vertical) {
response.setContentType("text/csv");
response.setHeader(CONTENT_DISPOSITION_HEADER_KEY, getContentDispostionHeader("csv"));
StringWriter writer = new StringWriter();
//using custom delimiter and quote character
CSVWriter csvWriter = new CSVWriter(writer);
if (vertical) {
csvWriter.writeNext(new String[]{"name", "value"});
for (Map.Entry<String, Object> entry : currentProfile.getProperties().entrySet()) {
csvWriter.writeNext(new String[]{entry.getKey(), entry.getValue().toString().trim().replace("\n", "")});
}
} else {
Set<String> keySet = currentProfile.getProperties().keySet();
List<String> values = new ArrayList<>();
for (Object value : currentProfile.getProperties().values()) {
values.add(value.toString().trim().replace("\n", ""));
}
csvWriter.writeNext(keySet.toArray(new String[0]));
csvWriter.writeNext(values.toArray(new String[0]));
}
Response.ResponseBuilder responseBuilder = Response.ok(writer.toString());
return responseBuilder.build();
}
private Response prepareJsonFileToDownload(Profile currentProfile) throws JsonProcessingException {
response.setContentType("text/json");
response.setHeader(CONTENT_DISPOSITION_HEADER_KEY, getContentDispostionHeader("json"));
ObjectMapper mapper = new ObjectMapper();
String jsonContent = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(currentProfile.getProperties());
return Response.ok(jsonContent).build();
}
private Response prepareYamlFileToDownload(Profile currentProfile, boolean asTextFile) throws JsonProcessingException {
response.setContentType("text/" + (asTextFile ? "plain" : "yaml"));
response.setHeader(CONTENT_DISPOSITION_HEADER_KEY, getContentDispostionHeader((asTextFile ? "txt" : "yml")));
YAMLFactory yf = new YAMLFactory();
ObjectMapper mapper = new ObjectMapper(yf);
String yamlContent = mapper.writeValueAsString(currentProfile.getProperties());
return Response.ok(yamlContent).build();
}
}