Commit 3efbc79f authored by Yong Liu's avatar Yong Liu
Browse files

implement cube for REST API.

parent 13955240
package com.nesstar.nesstardrop;
import com.nesstar.nesstardrop.common.ServerHandler;
import com.nesstar.nesstardrop.resources.CorrelationResource;
import com.nesstar.nesstardrop.resources.LoginResource;
import com.nesstar.nesstardrop.resources.LoginStatusResource;
import com.nesstar.nesstardrop.resources.LogoutResource;
import com.nesstar.nesstardrop.resources.RegressionResource;
import com.nesstar.nesstardrop.resources.StudyListResource;
import com.nesstar.nesstardrop.resources.StudyResource;
import com.nesstar.nesstardrop.resources.TabulateResource;
import com.nesstar.nesstardrop.resources.TranslationResource;
import com.nesstar.nesstardrop.resources.VariableGroupResource;
import com.nesstar.nesstardrop.resources.VariableResource;
import com.yammer.dropwizard.Service;
import com.yammer.dropwizard.config.Bootstrap;
import com.yammer.dropwizard.config.Environment;
import com.yammer.dropwizard.config.FilterBuilder;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.servlets.CrossOriginFilter;
public class NesstarDropService extends Service<NesstarDropConfiguration> {
public static void main(String[] args) throws Exception {
new NesstarDropService().run(args);
}
@Override
public void initialize(Bootstrap<NesstarDropConfiguration> bootstrap) {
bootstrap.setName("NesstarDrop");
}
@Override
public void run(NesstarDropConfiguration configuration, Environment environment) {
final String serverURI = configuration.getServerURI();
final String userId = configuration.getUserId();
final String password = configuration.getPassword();
ServerHandler.setServerURI(serverURI, userId, password);
environment.setSessionHandler(new SessionHandler());
environment.addResource(new CorrelationResource());
environment.addResource(new LoginResource());
environment.addResource(new LoginStatusResource());
environment.addResource(new LogoutResource());
environment.addResource(new RegressionResource());
environment.addResource(new StudyListResource());
environment.addResource(new StudyResource());
environment.addResource(new TabulateResource());
environment.addResource(new TranslationResource());
environment.addResource(new VariableGroupResource());
environment.addResource(new VariableResource());
FilterBuilder filterConfig = environment.addFilter(CrossOriginFilter.class, "*");
filterConfig.setInitParam(CrossOriginFilter.PREFLIGHT_MAX_AGE_PARAM, String.valueOf(60 * 60 * 24)); // 1 day
filterConfig.setInitParam(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*");
}
}
package com.nesstar.nesstardrop;
import com.nesstar.nesstardrop.common.ServerHandler;
import com.nesstar.nesstardrop.resources.CorrelationResource;
import com.nesstar.nesstardrop.resources.CubeResource;
import com.nesstar.nesstardrop.resources.LoginResource;
import com.nesstar.nesstardrop.resources.LoginStatusResource;
import com.nesstar.nesstardrop.resources.LogoutResource;
import com.nesstar.nesstardrop.resources.RegressionResource;
import com.nesstar.nesstardrop.resources.StudyListResource;
import com.nesstar.nesstardrop.resources.StudyResource;
import com.nesstar.nesstardrop.resources.TabulateResource;
import com.nesstar.nesstardrop.resources.TranslationResource;
import com.nesstar.nesstardrop.resources.VariableGroupResource;
import com.nesstar.nesstardrop.resources.VariableResource;
import com.yammer.dropwizard.Service;
import com.yammer.dropwizard.config.Bootstrap;
import com.yammer.dropwizard.config.Environment;
import com.yammer.dropwizard.config.FilterBuilder;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.servlets.CrossOriginFilter;
public class NesstarDropService extends Service<NesstarDropConfiguration> {
public static void main(String[] args) throws Exception {
new NesstarDropService().run(args);
}
@Override
public void initialize(Bootstrap<NesstarDropConfiguration> bootstrap) {
bootstrap.setName("NesstarDrop");
}
@Override
public void run(NesstarDropConfiguration configuration, Environment environment) {
final String serverURI = configuration.getServerURI();
final String userId = configuration.getUserId();
final String password = configuration.getPassword();
ServerHandler.setServerURI(serverURI, userId, password);
environment.setSessionHandler(new SessionHandler());
environment.addResource(new CorrelationResource());
environment.addResource(new LoginResource());
environment.addResource(new LoginStatusResource());
environment.addResource(new LogoutResource());
environment.addResource(new RegressionResource());
environment.addResource(new StudyListResource());
environment.addResource(new StudyResource());
environment.addResource(new TabulateResource());
environment.addResource(new TranslationResource());
environment.addResource(new VariableGroupResource());
environment.addResource(new VariableResource());
environment.addResource(new CubeResource());
FilterBuilder filterConfig = environment.addFilter(CrossOriginFilter.class, "*");
filterConfig.setInitParam(CrossOriginFilter.PREFLIGHT_MAX_AGE_PARAM, String.valueOf(60 * 60 * 24)); // 1 day
filterConfig.setInitParam(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*");
}
}
package com.nesstar.nesstardrop.common;
import com.nesstar.api.Bank;
import com.nesstar.api.Server;
import com.nesstar.api.Study;
import com.nesstar.api.Variable;
import com.nesstar.api.VariableGroup;
import java.util.ArrayList;
import java.util.List;
public final class ResourceExtractor {
private ResourceExtractor() {
}
public static Study getStudy(String studyId, Server server) throws MissingResourceException {
Study study = server.getBank(Study.class).get(studyId);
if (study == null) {
throw new MissingResourceException(getErrorMessage("study", studyId));
}
return study;
}
private static String getErrorMessage(String type, String id) {
return "No " + type + " with id '" + id + "' was found.";
}
public static Variable getVariable(String variableId, Server server) throws MissingResourceException {
if (variableId == null) {
return null;
}
else {
return getVariable(server.getBank(Variable.class), variableId);
}
}
private static Variable getVariable(Bank<Variable> variableBank, String variableId) throws MissingResourceException {
Variable variable = variableBank.get(variableId);
if (variable == null) {
throw new MissingResourceException(getErrorMessage("variable", variableId));
}
return variable;
}
public static List<Variable> getVariables(String[] variableIds, Server server) throws MissingResourceException {
Bank<Variable> variableBank = server.getBank(Variable.class);
List<Variable> variables = new ArrayList<Variable>();
if (variableIds != null) {
for (String variableId : variableIds) {
variables.add(getVariable(variableBank, variableId));
}
}
return variables;
}
public static VariableGroup getVariableGroup(String variableGroupId, Server server) throws MissingResourceException {
Bank<VariableGroup> variableGroupBank = server.getBank(VariableGroup.class);
VariableGroup variableGroup = variableGroupBank.get(variableGroupId);
if (variableGroup == null) {
throw new MissingResourceException(getErrorMessage("variable group", variableGroupId));
}
return variableGroup;
}
}
package com.nesstar.nesstardrop.common;
import com.nesstar.api.Bank;
import com.nesstar.api.Server;
import com.nesstar.api.Study;
import com.nesstar.api.Variable;
import com.nesstar.api.VariableGroup;
import com.nesstar.api.cube.Cube;
import java.util.ArrayList;
import java.util.List;
public final class ResourceExtractor {
private ResourceExtractor() {
}
public static Study getStudy(String studyId, Server server) throws MissingResourceException {
Study study = server.getBank(Study.class).get(studyId);
if (study == null) {
throw new MissingResourceException(getErrorMessage("study", studyId));
}
return study;
}
private static String getErrorMessage(String type, String id) {
return "No " + type + " with id '" + id + "' was found.";
}
public static Variable getVariable(String variableId, Server server) throws MissingResourceException {
if (variableId == null) {
return null;
}
else {
return getVariable(server.getBank(Variable.class), variableId);
}
}
private static Variable getVariable(Bank<Variable> variableBank, String variableId) throws MissingResourceException {
Variable variable = variableBank.get(variableId);
if (variable == null) {
throw new MissingResourceException(getErrorMessage("variable", variableId));
}
return variable;
}
public static List<Variable> getVariables(String[] variableIds, Server server) throws MissingResourceException {
Bank<Variable> variableBank = server.getBank(Variable.class);
List<Variable> variables = new ArrayList<Variable>();
if (variableIds != null) {
for (String variableId : variableIds) {
variables.add(getVariable(variableBank, variableId));
}
}
return variables;
}
public static VariableGroup getVariableGroup(String variableGroupId, Server server) throws MissingResourceException {
Bank<VariableGroup> variableGroupBank = server.getBank(VariableGroup.class);
VariableGroup variableGroup = variableGroupBank.get(variableGroupId);
if (variableGroup == null) {
throw new MissingResourceException(getErrorMessage("variable group", variableGroupId));
}
return variableGroup;
}
public static Cube getCube(String cubeId, Server server) throws MissingResourceException {
Cube cube = server.getBank(Cube.class).get(cubeId);
if (cube == null) {
throw new MissingResourceException(getErrorMessage("cude", cubeId));
}
return cube;
}
}
package com.nesstar.nesstardrop.request_objects;
import java.util.List;
import java.util.Map;
public class CubeRequest {
private String[] measures;
private List<Map<String, Object>> dimensions;
public List<Map<String, Object>> getDimensions() {
return dimensions;
}
public void setDimensions(List<Map<String, Object>> dimensions) {
this.dimensions = dimensions;
}
public String[] getMeasures() {
return measures;
}
public void setMeasures(String[] measures) {
this.measures = measures;
}
}
package com.nesstar.nesstardrop.resources;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import com.nesstar.api.NotAuthorizedException;
import com.nesstar.api.Server;
import com.nesstar.api.cube.Cell;
import com.nesstar.api.cube.Cube;
import com.nesstar.api.cube.Dimension;
import com.nesstar.api.cube.Level;
import com.nesstar.api.cube.Measure;
import com.nesstar.api.cube.Member;
import com.nesstar.api.cube.Slice;
import com.nesstar.api.cube.SliceBuilder;
import com.nesstar.api.cube.SliceCoordinates;
import com.nesstar.nesstardrop.common.Operation;
import com.nesstar.nesstardrop.common.OperationRunner;
import com.nesstar.nesstardrop.common.ResourceExtractor;
import com.nesstar.nesstardrop.common.ServerHandler;
import com.nesstar.nesstardrop.request_objects.CubeRequest;
import com.nesstar.nesstardrop.result_object_makers.DimensionMaker;
import com.nesstar.nesstardrop.result_object_makers.ErrorMaker;
import com.nesstar.nesstardrop.result_object_makers.MeasureMaker;
import com.yammer.metrics.annotation.Timed;
@Path("cube/{cubeId}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class CubeResource {
private Server server;
private Cube cube;
private List<Dimension> dimensions;
private List<Measure> measures;
private List<Map<String, Object>> values;
private List<Dimension> slicedimensions;
private List<Measure> slicemeasures;
public Map<Dimension, List<Member>> dimensionMemberList;
private boolean isInvalidRequest(CubeRequest cubeRequest) {
/*
* if (cubeRequest.getDimensions() == null || cubeRequest.getDimensions().length == 0 || cubeRequest.getMeasures() == null || cubeRequest.getMeasures().length == 0) { return true; }
*/
return false;
}
@POST
@Timed
public Object cube(final CubeRequest cubeRequest, @PathParam("cubeId") final String cubeId, @Context final HttpServletRequest request) {
values = new ArrayList<Map<String, Object>>();
dimensionMemberList = new LinkedHashMap<Dimension, List<Member>>();
if (isInvalidRequest(cubeRequest)) {
return ErrorMaker.getBadRequestError("The request must specify at least one break variable or one measure variable.");
}
return OperationRunner.runWithExceptionHandling(request, new Operation() {
@Override
public Object run() throws Exception {
try {
server = ServerHandler.getServer(request);
} catch (IOException e) {
System.out.println("server error.");
}
cube = ResourceExtractor.getCube(cubeId, server);
dimensions = cube.getDimensions();
measures = cube.getMeasures();
performCube(cubeRequest, cube);
return getCubeObject(cube);
}
});
}
@GET
@Timed
public Object getCubeMetadata(@PathParam("cubeId") final String cubeId, @Context final HttpServletRequest request) {
values = null;
dimensionMemberList = new LinkedHashMap<Dimension, List<Member>>();
return OperationRunner.runWithExceptionHandling(request, new Operation() {
@Override
public Object run() throws Exception {
try {
server = ServerHandler.getServer(request);
} catch (IOException e) {
System.out.println("server error.");
}
cube = ResourceExtractor.getCube(cubeId, server);
slicedimensions = cube.getDimensions();
slicemeasures = cube.getMeasures();
return getCubeObject(cube);
}
});
}
private Dimension getDimension(String id) {
for (Dimension dimension : dimensions) {
if (dimension.getId().equals(id)) {
return dimension;
}
}
return null;
}
private Measure getMeasure(String id) {
for (Measure measure : measures) {
if (measure.getId().equals(id)) {
return measure;
}
}
return null;
}
@SuppressWarnings("unchecked")
private void performCube(CubeRequest cubeRequest, Cube cube) throws NotAuthorizedException, IOException {
SliceBuilder sliceBuilder = new SliceBuilder();
slicedimensions = new ArrayList<Dimension>();
for (Map<String, Object> objectmap : cubeRequest.getDimensions()) {
Dimension dimension = getDimension((String) objectmap.get("id"));
slicedimensions.add(dimension);
List<Member> members = new ArrayList<Member>();
if (objectmap.get("members") != null) {
for (String id : (List<String>) objectmap.get("members")) {
members.add(getMember(dimension, id));
}
}
this.dimensionMemberList.put(dimension, members);
if (members.size() == 0) {
sliceBuilder.addDimension(dimension);
} else {
sliceBuilder.addDimension(dimension, members.toArray(new Member[members.size()]));
}
}
slicemeasures = new ArrayList<Measure>();
for (String id : cubeRequest.getMeasures()) {
Measure measure = getMeasure(id);
sliceBuilder.addMeasure(measure);
slicemeasures.add(measure);
}
Slice slice = cube.getSlice(sliceBuilder);
getValues(slicedimensions, slicemeasures, slice, new Stack<Member>());
}
private Member getMember(Dimension dimension, String id) throws NotAuthorizedException, IOException {
List<Level> levels = dimension.getHierarchies().get(0).getLevels();
for (Level level : levels) {
List<Member> levelMembers = level.getMembers();
for (Member member : levelMembers) {
if (member.getId().equals(id)) {
return member;
}
}
}
return null;
}
private void getValues(List<Dimension> dimensions, List<Measure> measures, Slice slice, Stack<Member> coords) throws IOException, NotAuthorizedException {
int depth = coords.size();
Dimension dimension = dimensions.get(depth);
List<Member> members = this.dimensionMemberList.get(dimension);
if (members == null || members.size() == 0) {
members = DimensionMaker.getMembersFromDimension(dimension);
}
for (Member member : members) {
coords.push(member);
if (depth == dimensions.size() - 1) {
SliceCoordinates coordinates = new SliceCoordinates();
List<Map<String, Object>> dimensionvaluelist = new ArrayList<Map<String, Object>>();
List<Map<String, String>> dimensionmaplist = new ArrayList<Map<String, String>>();
for (int i = 0; i <= depth; i++) {
Member coordMember = coords.get(i);
Dimension coordDim = dimensions.get(i);
coordinates.setValue(coordDim, coordMember);
Map<String, String> dimensionmap = new LinkedHashMap<String, String>();
dimensionmap.put("category", coordDim.getId());
dimensionmap.put("member", coordMember.getId());
dimensionmaplist.add(dimensionmap);
}
for (Measure measure : measures) {
Cell cell = slice.getValue(measure, coordinates);
if (cell != null) {
Map<String, Object> dimensionvalues = new LinkedHashMap<String, Object>();
dimensionvalues.put("id", measure.getId());
dimensionvalues.put("value", cell.getValue());
dimensionvaluelist.add(dimensionvalues);
}
}
Map<String, Object> cols = new LinkedHashMap<String, Object>();
cols.put("coordinate", dimensionmaplist);
cols.put("value", dimensionvaluelist);
values.add(cols);
} else {
getValues(dimensions, measures, slice, coords);
}
coords.pop();
}
}
private Object getCubeObject(Cube cube) throws NotAuthorizedException, IOException {
Map<String, Object> cubeJsonObject = new LinkedHashMap<String, Object>();
cubeJsonObject.put("measures", MeasureMaker.getMeasureJsonObjectList(slicemeasures));
cubeJsonObject.put("dimensions", DimensionMaker.getDimensionJsonObjectList(slicedimensions));
if (this.values != null) {
cubeJsonObject.put("values", this.values);
}
HashMap<String, Object> result = new LinkedHashMap<String, Object>();
result.put("cube", cubeJsonObject);
return result;
}
}
package com.nesstar.nesstardrop.result_object_makers;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import com.nesstar.api.NotAuthorizedException;
import com.nesstar.api.cube.Dimension;
import com.nesstar.api.cube.Level;
import com.nesstar.api.cube.Member;
public class DimensionMaker {
public static Map<String, Object> getDimensionJsonObject(Dimension dimension) throws NotAuthorizedException, IOException {
Map<String, Object> objectmap = new LinkedHashMap<String, Object>();
objectmap.put("id", dimension.getId());
objectmap.put("label", dimension.getLabel());
List<Member> memberlist = getMembersFromDimension(dimension);
if (memberlist.size() > 0) {
objectmap.put("members", MemberMaker.getMemberJsonObjectList(dimension, memberlist));
}
objectmap.put("Hierarchy", HierarchyMaker.getHierarchyJsonObjectList(dimension, dimension.getHierarchies()));
return objectmap;
}
public static List<Member> getMembersFromDimension(Dimension dimension) throws NotAuthorizedException, IOException {
List<Member> members = new LinkedList<Member>();
List<Level> levels = dimension.getHierarchies().get(0).getLevels();
for (Level level : levels) {
List<Member> levelMembers = level.getMembers();
members.addAll(levelMembers);
}
return members;
}
public static List<Map<String, Object>> getDimensionJsonObjectList(Collection<Dimension> dimensions) throws NotAuthorizedException, IOException {
List<Map<String, Object>> dimensionList = new ArrayList<Map<String, Object>>();
for (Dimension dimension : dimensions) {
dimensionList.add(getDimensionJsonObject(dimension));
}
return dimensionList;
}
}
package com.nesstar.nesstardrop.result_object_makers;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;