Commit 3aa18499 authored by Eirik Alvær's avatar Eirik Alvær
parents dc444401 847d0f3f
package com.nesstar.rest;
import com.nesstar.rest.filters.TabulationEntityTagFilter;
import com.nesstar.rest.filters.CorrelationEntityTagFilter;
import com.nesstar.rest.filters.EntityTagFilter;
import com.nesstar.rest.filters.CubeEntityTagFilter;
import com.nesstar.rest.filters.RegressionEntityTagFilter;
import com.nesstar.rest.filters.LanguageFilter;
import com.nesstar.rest.filters.CommonEntityTagFilter;
import com.nesstar.rest.resources.SearchResource;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.servlets.CrossOriginFilter;
import com.nesstar.rest.common.ServerHandler;
import com.nesstar.rest.filters.CommonEntityTagFilter;
import com.nesstar.rest.filters.EntityTagFilter;
import com.nesstar.rest.filters.LanguageFilter;
import com.nesstar.rest.filters.TabulationEntityTagFilter;
import com.nesstar.rest.healthchecks.NesstarHealthCheck;
import com.nesstar.rest.resources.CorrelationResource;
import com.nesstar.rest.resources.CubeResource;
......@@ -27,26 +30,26 @@ import com.yammer.dropwizard.config.Bootstrap;
import com.yammer.dropwizard.config.Environment;
import com.yammer.dropwizard.config.FilterBuilder;
public final class NesstarDropService extends Service<NesstarDropConfiguration> {
public class NesstarDropService extends Service<NesstarDropConfiguration> {
private static final int SECONDSINONEDAY = 60 * 60 * 24;
public static void main(String[] args) throws Exception {
new NesstarDropService().run(args);
}
@Override
public void initialize(final Bootstrap<NesstarDropConfiguration> bootstrap) {
public void initialize(Bootstrap<NesstarDropConfiguration> bootstrap) {
bootstrap.setName("Nesstar-REST_API");
bootstrap.addBundle(new AssetsBundle("/assets/", "/"));
}
@Override
public void run(final NesstarDropConfiguration configuration, final Environment environment) {
final String serverURI = configuration.getServerURI();
final String userId = configuration.getUserId();
final String password = configuration.getPassword();
public void run(NesstarDropConfiguration configuration, Environment environment) {
String serverURI = configuration.getServerURI();
String userId = configuration.getUserId();
String password = configuration.getPassword();
environment.setSessionHandler(new SessionHandler());
final ServerHandler serverHandler = new ServerHandler(serverURI, userId, password);
ServerHandler serverHandler = new ServerHandler(serverURI, userId, password);
environment.addResource(new CorrelationResource(serverHandler));
environment.addResource(new RegressionResource(serverHandler));
......@@ -63,14 +66,23 @@ public final class NesstarDropService extends Service<NesstarDropConfiguration>
environment.addHealthCheck(new NesstarHealthCheck(serverHandler));
final FilterBuilder filterConfig = environment.addFilter(CrossOriginFilter.class, "*");
FilterBuilder filterConfig = environment.addFilter(CrossOriginFilter.class, "*");
filterConfig.setInitParam(CrossOriginFilter.PREFLIGHT_MAX_AGE_PARAM, String.valueOf(SECONDSINONEDAY)); // 1 day
filterConfig.setInitParam(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*");
final TabulationEntityTagFilter tabulationETagFilter = new TabulationEntityTagFilter(serverHandler);
TabulationEntityTagFilter tabulationETagFilter = new TabulationEntityTagFilter(serverHandler);
environment.addFilter(tabulationETagFilter, "/study/*");
final EntityTagFilter eTagFilter = new CommonEntityTagFilter(serverHandler);
CorrelationEntityTagFilter correlationEntityTagFilter = new CorrelationEntityTagFilter(serverHandler);
environment.addFilter(correlationEntityTagFilter, "/study/*");
RegressionEntityTagFilter regressionEntityTagFilter = new RegressionEntityTagFilter(serverHandler);
environment.addFilter(regressionEntityTagFilter, "/study/*");
CubeEntityTagFilter cubeETagFilter = new CubeEntityTagFilter(serverHandler);
environment.addFilter(cubeETagFilter, "/cube/*");
EntityTagFilter eTagFilter = new CommonEntityTagFilter(serverHandler);
environment.addFilter(eTagFilter, "/*");
environment.addFilter(LanguageFilter.class, "*");
......
......@@ -11,32 +11,32 @@ import java.util.jar.Manifest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class Version {
public class Version {
private static String versionNumber;
private static final Logger LOG = LoggerFactory.getLogger(Version.class);
private static Version instance = new Version();
private static String versionNumber = readVersionNumber();
private Version() {
LOG.debug("Initializing version");
versionNumber = readVersionNumber();
}
public static String version() {
return getInstance().getVersion();
}
private static Version getInstance() {
return instance;
return VersionHolder.INSTANCE;
}
private String getVersion() {
return versionNumber;
}
private static String readVersionNumber() {
private String readVersionNumber() {
LOG.debug("Reading version number");
String version;
try {
final Manifest manifest = getManifest();
Manifest manifest = getManifest();
version = getVersionFromManifest(manifest);
} catch (IOException e) {
LOG.warn("Exception occurred while reading manifest: {}, {}", e.getMessage(), e.getCause());
......@@ -44,33 +44,35 @@ public final class Version {
}
return version;
}
private static Manifest getManifest() throws IOException {
private Manifest getManifest() throws IOException {
LOG.debug("Getting manifest");
final Enumeration manifestSources = Thread.currentThread().getContextClassLoader().getResources(JarFile.MANIFEST_NAME);
final Manifest manifest = new Manifest();
Enumeration manifestSources = Thread.currentThread().getContextClassLoader().getResources(JarFile.MANIFEST_NAME);
while (manifestSources.hasMoreElements()) {
final URL url = (URL) manifestSources.nextElement();
final InputStream stream = url.openStream();
if (stream == null) {
continue;
}
manifest.read(stream);
final Attributes attributes = manifest.getMainAttributes();
final String mainClassName = attributes.getValue("Main-Class");
if ("com.nesstar.rest.NesstarDropService".equals(mainClassName)) {
return manifest;
URL url = (URL) manifestSources.nextElement();
InputStream stream = url.openStream();
if (stream != null) {
Manifest manifest = new Manifest(stream);
Attributes attributes = manifest.getMainAttributes();
String mainClassName = attributes.getValue("Main-Class");
if ("com.nesstar.rest.NesstarDropService".equals(mainClassName)) {
return manifest;
}
}
}
return null;
}
private static String getVersionFromManifest(final Manifest manifest) throws IOException {
private String getVersionFromManifest(Manifest mf) throws IOException {
String version = null;
if (manifest != null) {
final Attributes attributes = manifest.getMainAttributes();
if (mf != null) {
Attributes attributes = mf.getMainAttributes();
version = attributes.getValue("Implementation-Version");
}
return version;
}
private static class VersionHolder {
private static final Version INSTANCE = new Version();
}
}
......@@ -4,7 +4,7 @@ import com.nesstar.api.Category;
import com.nesstar.api.NesstarObject;
import com.nesstar.api.Variable;
import com.nesstar.api.analysis.Statistic;
import com.nesstar.api.cube.Cube;
import com.nesstar.rest.filters.CubeEntityTagFilter;
import com.nesstar.rest.request_objects.CubeRequest;
import javax.servlet.http.HttpServletRequest;
......@@ -51,9 +51,8 @@ public final class ETag {
return createETag(new ETagGenerator(data));
}
public static ETag generateEtagForTabulation(final TabulationClassVariables classVariables, final HttpServletRequest request) {
public static ETag generateEtagForTabulation(final TabulationClassVariables classVariables, final String url) {
ETagData data = new ETagData();
String url = request.getRequestURL().toString();
data.add(url).add(classVariables.getStudy());
for (Variable variable : classVariables.getBreakVariables()) {
......@@ -75,19 +74,16 @@ public final class ETag {
}
data.add(classVariables.getCaseSubset());
return createETag(new ETagGenerator(data));
return ETag.createETag(new ETagGenerator(data));
}
public static ETag generateEtagForCube(final Cube cube, final CubeRequest cubeRequest, final HttpServletRequest request) {
ETagData data = new ETagData();
String url = request.getRequestURL().toString();
data.add(url).add(cube).add(cubeRequest);
public static ETag generateEtagForCube(final CubeRequest cubeRequest, final String url, final String cubeId) {
ETagData data = CubeEntityTagFilter.generateETagData(cubeRequest, url, cubeId);
return createETag(new ETagGenerator(data));
}
public static ETag generateEtagForCorrelation(final CorrelationClassVariables classVariables, final HttpServletRequest request) {
public static ETag generateEtagForCorrelation(final CorrelationClassVariables classVariables, final String url) {
ETagData data = new ETagData();
String url = request.getRequestURL().toString();
data.add(url).add(classVariables.getStudy());
for (Variable variable: classVariables.getCorrelationVariables()) {
......@@ -104,9 +100,8 @@ public final class ETag {
return createETag(new ETagGenerator(data));
}
public static ETag generateEtagForRegression(final RegressionClassVariables classVariables, final HttpServletRequest request) {
public static ETag generateEtagForRegression(final RegressionClassVariables classVariables, final String url) {
ETagData data = new ETagData();
String url = request.getRequestURL().toString();
data.add(url).add(classVariables.getStudy());
for (Variable variable: classVariables.getIndependentVariables()) {
......
......@@ -4,7 +4,6 @@ import java.io.IOException;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -12,7 +11,6 @@ import org.slf4j.LoggerFactory;
import com.nesstar.api.NesstarList;
import com.nesstar.api.NesstarObject;
import com.nesstar.api.NotAuthorizedException;
import com.nesstar.rest.request_objects.CubeRequest;
public class ETagData {
protected static final Date ZERODATE = new Date(0L);
......@@ -29,20 +27,13 @@ public class ETagData {
return this;
}
public ETagData addNesstarObject(final NesstarObject object) {
private ETagData addNesstarObject(final NesstarObject object) {
data.add(getObjectId(object));
data.add(getTimestamp(object));
return this;
}
public ETagData addCubeRequest(final CubeRequest request) {
addDimensionsFromCubeRequest(request);
addMeasuresFromCubeRequest(request);
return this;
}
public String getString() {
final StringBuilder stringBuilder = new StringBuilder();
for (final String str : data) {
......@@ -118,28 +109,5 @@ public class ETagData {
return latest;
}
private void addDimensionsFromCubeRequest(final CubeRequest request) {
final String[] dimensions = getDimensionIDs(request);
for (final String dimension : dimensions) {
data.add(dimension);
}
}
private void addMeasuresFromCubeRequest(final CubeRequest request) {
for (final String measure : request.getMeasures()) {
data.add(measure);
}
}
private String[] getDimensionIDs(final CubeRequest request) {
String[] dimensionIDs = new String[request.getDimensions().size()];
for (int i = 0; i < dimensionIDs.length; i++) {
final Map<String, Object> map = request.getDimensions().get(i);
dimensionIDs[i] = (String) map.get("id");
}
return dimensionIDs;
}
}
......@@ -21,7 +21,6 @@ import com.nesstar.rest.common.ETag;
import com.nesstar.rest.common.ETagData;
import com.nesstar.rest.common.ETagGenerator;
import com.nesstar.rest.common.ServerHandler;
import com.nesstar.rest.request_objects.CubeRequest;
public class CommonEntityTagFilter extends EntityTagFilter {
private static final Logger LOG = LoggerFactory.getLogger(CommonEntityTagFilter.class);
......@@ -177,29 +176,10 @@ public class CommonEntityTagFilter extends EntityTagFilter {
String url = request.getRequestURL().toString();
ETagData data = new ETagData();
data.add(url).add(object);
if (object instanceof Cube) {
addDataFromCubeRequest(data, request);
}
return ETag.createETag(new ETagGenerator(data));
}
private void addDataFromCubeRequest(ETagData data, HttpServletRequest request) {
CubeRequest cubeRequest = getCubeRequest(request);
if (cubeRequest != null) {
data.addCubeRequest(cubeRequest);
}
}
private CubeRequest getCubeRequest(HttpServletRequest request) {
String cubeRequestQuery = request.getParameter("q");
CubeRequest cubeRequest = null;
if (cubeRequestQuery != null) {
cubeRequest = CubeRequest.valueOf(cubeRequestQuery);
}
return cubeRequest;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
......@@ -210,5 +190,5 @@ public class CommonEntityTagFilter extends EntityTagFilter {
public void destroy() {
// No implementation necessary
}
}
package com.nesstar.rest.filters;
import com.nesstar.api.Study;
import com.nesstar.api.Variable;
import com.nesstar.rest.common.ETagData;
import com.nesstar.rest.common.MissingResourceException;
import com.nesstar.rest.common.ResourceExtractor;
import com.nesstar.rest.common.ServerHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
public class CorrelationEntityTagFilter extends OperationEntityTagFilter {
private static final Logger LOG = LoggerFactory.getLogger(CorrelationEntityTagFilter.class);
public CorrelationEntityTagFilter(ServerHandler serverHandler) {
super(serverHandler);
}
@Override
protected ETagData generateETagData(final HttpServletRequest request) {
ETagData data = new ETagData();
String url = request.getRequestURL().toString();
data.add(url);
Study study = getStudy(request);
if (study != null) {
data.add(study);
}
List<Variable> correlationVariables = getCorrelationVariables(request);
List<Variable> weightVariables = getWeightVariables(request);
for (Variable variable : correlationVariables) {
data.add(variable);
}
for (Variable weightVariable : weightVariables) {
data.add(weightVariable);
}
data.add(getCaseSubset(request));
data.add(getMissDeletion(request));
return data;
}
private List<Variable> getCorrelationVariables(HttpServletRequest request) {
String[] variableIDs = getVariableIDs(request, "corrVar");
try {
return ResourceExtractor.getVariables(variableIDs, getServer());
} catch (MissingResourceException e) {
LOG.warn("Missing variables");
} catch (IOException e) {
LOG.warn("IOException when getting correlation variables");
}
return new LinkedList<Variable>();
}
private List<Variable> getWeightVariables(HttpServletRequest request) {
String[] weightVariableIDs = getVariableIDs(request, "wgtVar");
try {
return ResourceExtractor.getVariables(weightVariableIDs, getServer());
} catch (MissingResourceException e) {
LOG.warn("Missing weight variables");
} catch (IOException e) {
LOG.warn("IOException when getting weight variables");
}
return null;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// No implementation necessary
}
@Override
public void destroy() {
// No implementation necessary
}
}
package com.nesstar.rest.filters;
import com.nesstar.rest.common.ETagData;
import com.nesstar.rest.common.ServerHandler;
import com.nesstar.rest.request_objects.CubeRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
public class CubeEntityTagFilter extends OperationEntityTagFilter {
private static final Logger LOG = LoggerFactory.getLogger(CubeEntityTagFilter.class);
public CubeEntityTagFilter(ServerHandler serverHandler) {
super(serverHandler);
}
@Override
protected ETagData generateETagData(final HttpServletRequest request) {
CubeRequest cubeRequest = getCubeRequest(request);
String url = request.getRequestURL().toString();
String cubeId = getCubeId(request);
return generateETagData(cubeRequest, url, cubeId);
}
public static ETagData generateETagData(final CubeRequest cubeRequest, final String url, final String cubeId) {
ETagData data = new ETagData();
data.add(url);
if (cubeRequest != null) {
final String[] dimensions = getDimensionIDs(cubeRequest);
for (final String dimension : dimensions) {
data.add(dimension);
}
for (final String measure : cubeRequest.getMeasures()) {
data.add(measure);
}
}
return data;
}
private CubeRequest getCubeRequest(HttpServletRequest request) {
String cubeRequestQuery = request.getParameter("q");
CubeRequest cubeRequest = null;
if (cubeRequestQuery != null) {
cubeRequest = CubeRequest.valueOf(cubeRequestQuery);
}
return cubeRequest;
}
private String getCubeId(final HttpServletRequest request) {
String[] parts = getUriPartsFromRequest(request);
if (parts.length >= 2) {
return parts[1];
}
return null;
}
private static String[] getDimensionIDs(final CubeRequest request) {
String[] dimensionIDs = new String[request.getDimensions().size()];
for (int i = 0; i < dimensionIDs.length; i++) {
final Map<String, Object> map = request.getDimensions().get(i);
dimensionIDs[i] = (String) map.get("id");
}
return dimensionIDs;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// No implementation necessary
}
@Override
public void destroy() {
// No implementation necessary
}
}
......@@ -30,7 +30,7 @@ public abstract class EntityTagFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
if (requestHasETag(httpRequest) && checkForMatchingETag(httpRequest)) {
return304Header(httpResponse);
} else {
......
package com.nesstar.rest.filters;
import com.nesstar.api.Study;
import com.nesstar.rest.common.ServerHandler;
import com.nesstar.rest.common.ETag;
import com.nesstar.rest.common.ETagData;
import com.nesstar.rest.common.ETagGenerator;
import com.nesstar.rest.common.ResourceExtractor;
import com.nesstar.rest.common.MissingResourceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public abstract class OperationEntityTagFilter extends EntityTagFilter {
private static final Logger LOG = LoggerFactory.getLogger(OperationEntityTagFilter.class);
public OperationEntityTagFilter(ServerHandler serverHandler) {
super(serverHandler);
}
@Override
protected boolean checkForMatchingETag(HttpServletRequest request) {
ETag etag = getEtagFromRequest(request);
return etagsMatch(request, etag);
}
protected ETag getEtagFromRequest(HttpServletRequest request) {
ETagData data = generateETagData(request);
return ETag.createETag(new ETagGenerator(data));
}
protected Study getStudy(HttpServletRequest request) {
String id = getStudyIdFromRequest(request);
Study study = null;
try {
study = ResourceExtractor.getStudy(id, getServer());
} catch (MissingResourceException e) {
LOG.warn("Missing study {}", id);
} catch (IOException e) {
LOG.warn("IOException when getting study: {}", id);
}
return study;
}
protected String getStudyIdFromRequest(HttpServletRequest request) {
String[] parts = getUriPartsFromRequest(request);
if (parts.length >= 2) {
return parts[1];
}
return null;
}
protected String[] getVariableIDs(HttpServletRequest request, String queryName) {
String[] vars = request.getParameterValues(queryName);
if (vars == null) {
vars = new String[0];
}
return vars;
}
protected String getCaseSubset(HttpServletRequest request) {
return request.getParameter("caseSubset");
}
protected String getMissDeletion(HttpServletRequest request) {
return request.getParameter("missDeletion");
}
protected abstract ETagData generateETagData(final HttpServletRequest request);
@Override
public abstract void init(FilterConfig filterConfig) throws ServletException;
@Override
public abstract void destroy();
}
package com.nesstar.rest.filters;
import com.nesstar.api.Study;
import com.nesstar.api.Variable;
import com.nesstar.rest.common.ETagData;
import com.nesstar.rest.common.MissingResourceException;
import com.nesstar.rest.common.ResourceExtractor;
import com.nesstar.rest.common.ServerHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
public class RegressionEntityTagFilter extends OperationEntityTagFilter {
private static final Logger LOG = LoggerFactory.getLogger(RegressionEntityTagFilter.class);
public RegressionEntityTagFilter(ServerHandler serverHandler) {
super(serverHandler);
}
@Override
protected ETagData generateETagData(final HttpServletRequest request) {
ETagData data = new ETagData();
String url = request.getRequestURL().toString();
data.add(url);
Study study = getStudy(request);
if (study != null) {
data.add(study);
}
List<Variable> correlationVariables = getIndependentVariables(request);
List<Variable> weightVariables = getWeightVariables(request);
for (Variable variable : correlationVariables) {
data.add(variable);
}
for (Variable weightVariable : weightVariables) {
data.add(weightVariable);
}
data.add(getDependentVariable(request));
data.add(getCaseSubset(request));
data.add(getMissDeletion(request));
return data;
}