/*
* 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.usergrid.rest.test.resource.endpoints;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
import org.apache.usergrid.rest.test.resource.model.ApiResponse;
import org.apache.usergrid.rest.test.resource.model.Entity;
import org.apache.usergrid.rest.test.resource.model.QueryParameters;
import org.apache.usergrid.rest.test.resource.model.Token;
import org.apache.usergrid.rest.test.resource.state.ClientContext;
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import org.glassfish.jersey.media.multipart.FormDataMultiPart;
import org.glassfish.jersey.media.multipart.MultiPart;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* Base class that is extended by named endpoints.
* The NamedResource stores the parent of the class, the context in which the class operates and then Name of this resource
*/
public class NamedResource implements UrlResource {
public static String SLASH = "/";
protected final String name;
protected final ClientContext context;
/**
* Stores the path of the parent that called it. i.e If we had a ApplicationResource
* (an instance of a namedResource) this would contain the OrganizationResource.
*/
protected final UrlResource parent;
public NamedResource(final String name, final ClientContext context, final UrlResource parent) {
this.name = name;
this.context = context;
this.parent = parent;
}
@Override
public String getPath() {
return name + getMatrix();
}
@Override
public WebTarget getTarget() {
return getTarget(false);
}
@Override
public ClientContext getContext() {
return context;
}
public WebTarget getTarget(boolean useToken) {
return getTarget(useToken, null);
}
public WebTarget getTarget(boolean useToken, Token token) {
WebTarget resource = parent.getTarget().path(getPath());
token = token != null ? token : this.context.getToken();
//error checking
if (token == null) {
return resource;
}
return useToken ? resource.queryParam("access_token", token.getAccessToken()) : resource;
}
protected WebTarget addParametersToResource(WebTarget resource, final QueryParameters parameters) {
if (parameters == null) {
return resource;
}
if (parameters.getQuery() != null) {
resource = resource.queryParam("ql", parameters.getQuery());
}
if (parameters.getCursor() != null) {
resource = resource.queryParam("cursor", parameters.getCursor());
}
if (parameters.getStart() != null) {
resource = resource.queryParam("start", parameters.getStart().toString());
}
if (parameters.getLimit() != null) {
resource = resource.queryParam("limit", parameters.getLimit().toString());
}
if (parameters.getConnections() != null) {
resource = resource.queryParam("connections", parameters.getConnections());
}
//We can also post the params as queries
if (parameters.getFormPostData().size() > 0) {
Map<String, String> formData = parameters.getFormPostData();
Set<String> keySet = formData.keySet();
Iterator<String> keyIterator = keySet.iterator();
while (keyIterator.hasNext()) {
String key = keyIterator.next();
String value = formData.get(key);
resource = resource.queryParam(key, value);
}
}
return resource;
}
protected String getMatrixValue(final QueryParameters parameters) {
StringBuilder sb = new StringBuilder();
if (parameters == null) {
return null;
}
if (parameters.getQuery() != null) {
sb.append(";");
sb.append("ql").append("=").append(parameters.getQuery());
}
if (parameters.getCursor() != null) {
sb.append(";");
sb.append("cursor").append("=").append(parameters.getCursor());
}
if (parameters.getStart() != null) {
sb.append(";");
sb.append("start").append("=").append(parameters.getStart());
}
if (parameters.getLimit() != null) {
sb.append(";");
sb.append("limit").append("=").append(parameters.getLimit());
}
//We can also post the params as queries
if (parameters.getFormPostData().size() > 0) {
Map<String, String> formData = parameters.getFormPostData();
Set<String> keySet = formData.keySet();
Iterator<String> keyIterator = keySet.iterator();
while (keyIterator.hasNext()) {
if (sb.length() > 0)
sb.append(";");
String key = keyIterator.next();
String value = formData.get(key);
sb.append(key).append("=").append(value);
}
}
return sb.toString();
}
/**
* Need to refactor all instances of tokens to either be passed in or manually set during the test.
* There isn't any reason we would want a rest forwarding framework to set something on behave of the user.
*
* @param map
* @return
*/
//For edge cases like Organizations and Tokens
public ApiResponse post(Map map) {
return post(true, ApiResponse.class, map, null, false);
}
//For edge cases like Organizations and Tokens
public ApiResponse post(boolean useToken, Map map, QueryParameters queryParameters) {
return post(useToken, ApiResponse.class, map, queryParameters, false);
}
/**
* Need to refactor all instances of tokens to either be passed in or manually set during the test.
* There isn't any reason we would want a rest forwarding framework to set something on behave of the user.
* For edge cases like Organizations and Tokens
*/
public <T> T post(Class<T> type) {
return post(true, type, null, null, false);
}
/**
* Need to refactor all instances of tokens to either be passed in or manually set during the test.
* There isn't any reason we would want a rest forwarding framework to set something on behave of the user.
* For edge cases like Organizations and Tokens.
*/
public <T> T post(Class<T> type, Entity requestEntity) {
return post(true, type, requestEntity, null, false);
}
/**
* Need to refactor all instances of tokens to either be passed in or manually set during the test.
* There isn't any reason we would want a rest forwarding framework to set something on behave of the user.
* For edge cases like Organizations and Tokens
*/
public <T> T post(Class<T> type, Map requestEntity) {
return post(true, type, requestEntity, null, false);
}
public <T> T post(boolean useToken, Class<T> type, Map requestEntity) {
return post(useToken, type, requestEntity, null, false);
}
/**
* Used to test POST using form payloads.
*/
public <T> T post(Class<T> type, Form form) {
GenericType<T> gt = new GenericType<>((Class) type);
return getTarget().request()
.accept(MediaType.APPLICATION_JSON)
.post(javax.ws.rs.client.Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE), gt);
}
// Used for empty posts
public <T> T post(boolean useToken, Class<T> type, Map entity, final QueryParameters queryParameters) {
WebTarget resource = getTarget(useToken);
resource = addParametersToResource(resource, queryParameters);
Invocation.Builder builder = resource.request()
.accept(MediaType.APPLICATION_JSON);
// it's OK for the entity to be null
GenericType<T> gt = new GenericType<>((Class) type);
return builder.post(javax.ws.rs.client.Entity.json(entity), gt);
}
// Used for empty posts
public <T> T post(boolean useToken, Class<T> type, Map entity,
final QueryParameters queryParameters, boolean useBasicAuthentication) {
WebTarget resource = getTarget(useToken);
resource = addParametersToResource(resource, queryParameters);
GenericType<T> gt = new GenericType<>((Class) type);
if (useBasicAuthentication) {
HttpAuthenticationFeature feature = HttpAuthenticationFeature.basicBuilder()
.credentials("superuser", "superpassword").build();
return resource.register(feature).request()
.accept(MediaType.APPLICATION_JSON)
.post(javax.ws.rs.client.Entity.json(entity), gt);
}
return resource.request()
.accept(MediaType.APPLICATION_JSON)
.post(javax.ws.rs.client.Entity.json(entity), gt);
}
// Used for empty posts
public <T> T post(boolean useToken, Token tokenToUse , Class<T> type, Map entity,
final QueryParameters queryParameters, boolean useBasicAuthentication) {
WebTarget resource = getTarget( useToken,tokenToUse );
resource = addParametersToResource(resource, queryParameters);
GenericType<T> gt = new GenericType<>((Class) type);
if (useBasicAuthentication) {
HttpAuthenticationFeature feature = HttpAuthenticationFeature.basicBuilder()
.credentials("superuser", "superpassword").build();
return resource.register(feature).request()
.accept(MediaType.APPLICATION_JSON)
.post(javax.ws.rs.client.Entity.json(entity), gt);
}
return resource.request()
.accept(MediaType.APPLICATION_JSON)
.post(javax.ws.rs.client.Entity.json(entity), gt);
}
//For edge cases like Organizations and Tokens without any payload
public <T> T get(Class<T> type) {
return get(type, null, true);
}
//For edge cases like Organizations and Tokens without any payload
public <T> T get(Class<T> type, boolean useToken) {
return get(type, null, useToken);
}
public <T> T get(Class<T> type, QueryParameters queryParameters) {
return get(type, queryParameters, true);
}
public <T> T get(Class<T> type, QueryParameters queryParameters, boolean useToken) {
WebTarget resource = getTarget(useToken);
if (queryParameters != null) {
resource = addParametersToResource(resource, queryParameters);
}
GenericType<T> gt = new GenericType<>((Class) type);
return resource.request()
.accept(MediaType.APPLICATION_JSON)
.get(gt);
}
public String getMatrix() {
return "";
}
public ApiResponse post(boolean useToken, MultiPart multiPartForm) {
WebTarget resource = getTarget(useToken);
return resource.request().post(
javax.ws.rs.client.Entity.entity(multiPartForm, multiPartForm.getMediaType()), ApiResponse.class);
}
public ApiResponse post(MultiPart multiPartForm) {
return post(true, multiPartForm);
}
public ApiResponse put(boolean useToken, byte[] data, MediaType type) {
WebTarget resource = getTarget(useToken);
return resource.request().put(
javax.ws.rs.client.Entity.entity(data, type), ApiResponse.class);
}
public ApiResponse put(boolean useToken, org.apache.usergrid.rest.test.resource.model.Entity entity, QueryParameters queryParameters ) {
WebTarget resource = getTarget(useToken);
if( queryParameters != null ) {
resource = addParametersToResource(resource, queryParameters);
}
return resource.request().put(
javax.ws.rs.client.Entity.entity(entity, MediaType.APPLICATION_JSON_TYPE), ApiResponse.class);
}
public ApiResponse put(boolean useToken, org.apache.usergrid.rest.test.resource.model.Entity entity ) {
WebTarget resource = getTarget(useToken);
return resource.request().put(
javax.ws.rs.client.Entity.entity(entity, MediaType.APPLICATION_JSON_TYPE), ApiResponse.class);
}
public ApiResponse put(byte[] data, MediaType type) {
return put(true, data, type);
}
public ApiResponse put(boolean useToken, FormDataMultiPart multiPartForm) {
WebTarget resource = getTarget(useToken);
return resource.request().put(
javax.ws.rs.client.Entity.entity(multiPartForm, multiPartForm.getMediaType()), ApiResponse.class);
}
public ApiResponse put(FormDataMultiPart multiPartForm) {
return put(true, multiPartForm);
}
public InputStream getAssetAsStream(boolean useToken) {
WebTarget resource = getTarget(useToken);
return resource.request().accept(MediaType.APPLICATION_OCTET_STREAM_TYPE).get(InputStream.class);
}
public InputStream getAssetAsStream() {
return getAssetAsStream(true);
}
public ApiResponse delete() {
return delete(true);
}
public ApiResponse delete(boolean useToken) {
return getTarget(useToken).request().delete(ApiResponse.class);
}
public ApiResponse delete(boolean useToken, QueryParameters queryParameters) {
WebTarget resource = getTarget(useToken);
if (queryParameters != null) {
resource = addParametersToResource(resource, queryParameters);
}
return resource.request().delete(ApiResponse.class);
}
public NamedResource getSubResource(String path) {
return new NamedResource(path,context,this);
}
}