org.apache.usergrid.rest.management.organizations.OrganizationResource.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.usergrid.rest.management.organizations.OrganizationResource.java

Source

/*
 * 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.management.organizations;

import com.fasterxml.jackson.jaxrs.json.annotation.JSONP;
import org.apache.amber.oauth2.common.exception.OAuthSystemException;
import org.apache.commons.lang.NullArgumentException;
import org.apache.usergrid.exception.NotImplementedException;
import org.apache.usergrid.management.ActivationState;
import org.apache.usergrid.management.OrganizationConfig;
import org.apache.usergrid.management.OrganizationInfo;
import org.apache.usergrid.management.export.ExportService;
import org.apache.usergrid.persistence.entities.Export;
import org.apache.usergrid.rest.AbstractContextResource;
import org.apache.usergrid.rest.ApiResponse;
import org.apache.usergrid.rest.applications.ServiceResource;
import org.apache.usergrid.rest.exceptions.RedirectionException;
import org.apache.usergrid.rest.management.organizations.applications.ApplicationsResource;
import org.apache.usergrid.rest.management.organizations.users.UsersResource;
import org.apache.usergrid.rest.security.annotations.RequireOrganizationAccess;
import org.apache.usergrid.rest.security.annotations.RequireSystemAccess;
import org.apache.usergrid.rest.utils.JSONPUtils;
import org.apache.usergrid.security.oauth.ClientCredentialsInfo;
import org.apache.usergrid.security.tokens.exceptions.TokenException;
import org.apache.usergrid.services.ServiceResults;
import org.glassfish.jersey.server.mvc.Viewable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.util.*;

import static javax.servlet.http.HttpServletResponse.*;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;

@Component("org.apache.usergrid.rest.management.organizations.OrganizationResource")
@Scope("prototype")
@Produces({ MediaType.APPLICATION_JSON, "application/javascript", "application/x-javascript", "text/ecmascript",
        "application/ecmascript", "text/jscript" })
public class OrganizationResource extends AbstractContextResource {

    private static final Logger logger = LoggerFactory.getLogger(OrganizationsResource.class);

    @Autowired
    protected ExportService exportService;

    OrganizationInfo organization;

    public OrganizationResource() {
        if (logger.isTraceEnabled()) {
            logger.trace("OrganizationResource created");
        }
    }

    public OrganizationResource init(OrganizationInfo organization) {
        this.organization = organization;
        if (logger.isTraceEnabled()) {
            logger.trace("OrganizationResource initialized for org {}", organization.getName());
        }
        return this;
    }

    @Path("users")
    public UsersResource getOrganizationUsers(@Context UriInfo ui) throws Exception {
        return getSubResource(UsersResource.class).init(organization);
    }

    @Path("applications")
    public ApplicationsResource getOrganizationApplications(@Context UriInfo ui) throws Exception {
        return getSubResource(ApplicationsResource.class).init(organization);
    }

    @Path("apps")
    public ApplicationsResource getOrganizationApplications2(@Context UriInfo ui) throws Exception {
        return getSubResource(ApplicationsResource.class).init(organization);
    }

    @GET
    @JSONP
    @RequireOrganizationAccess
    @Produces({ MediaType.APPLICATION_JSON, "application/javascript" })
    public ApiResponse getOrganizationDetails(@Context UriInfo ui,
            @QueryParam("callback") @DefaultValue("callback") String callback) throws Exception {

        if (logger.isTraceEnabled()) {
            logger.trace("Get details for organization: {}", organization.getUuid());
        }

        ApiResponse response = createApiResponse();
        response.setProperty("organization", management.getOrganizationData(organization));

        return response;
    }

    @GET
    @Path("activate")
    @Produces(MediaType.TEXT_HTML)
    public Viewable activate(@Context UriInfo ui, @QueryParam("token") String token) {

        try {
            management.handleActivationTokenForOrganization(organization.getUuid(), token);
            return handleViewable("activate", this, organization.getName());
        } catch (TokenException e) {
            return handleViewable("bad_activation_token", this, organization.getName());
        } catch (RedirectionException e) {
            throw e;
        } catch (Exception e) {
            return handleViewable("error", e, organization.getName());
        }
    }

    @GET
    @Path("confirm")
    @Produces(MediaType.TEXT_HTML)
    public Viewable confirm(@Context UriInfo ui, @QueryParam("token") String token) {

        try {
            ActivationState state = management.handleActivationTokenForOrganization(organization.getUuid(), token);
            if (state == ActivationState.CONFIRMED_AWAITING_ACTIVATION) {
                return handleViewable("confirm", this, organization.getName());
            }
            return handleViewable("activate", this, organization.getName());
        } catch (TokenException e) {
            return handleViewable("bad_activation_token", this, organization.getName());
        } catch (RedirectionException e) {
            throw e;
        } catch (Exception e) {
            return handleViewable("error", e, organization.getName());
        }
    }

    @GET
    @Path("reactivate")
    @JSONP
    @Produces({ MediaType.APPLICATION_JSON, "application/javascript" })
    public ApiResponse reactivate(@Context UriInfo ui,
            @QueryParam("callback") @DefaultValue("callback") String callback) throws Exception {

        logger.info("Send activation email for organization: {}", organization.getUuid());

        ApiResponse response = createApiResponse();

        management.startOrganizationActivationFlow(organization);

        response.setAction("reactivate organization");
        return response;
    }

    @RequireOrganizationAccess
    @GET
    @Path("feed")
    @JSONP
    @Produces({ MediaType.APPLICATION_JSON, "application/javascript" })
    public ApiResponse getFeed(@Context UriInfo ui,
            @QueryParam("callback") @DefaultValue("callback") String callback) throws Exception {

        ApiResponse response = createApiResponse();
        response.setAction("get organization feed");

        ServiceResults results = management.getOrganizationActivity(organization);
        response.setEntities(results.getEntities());
        response.setSuccess();

        return response;
    }

    @RequireOrganizationAccess
    @GET
    @Path("credentials")
    @JSONP
    @Produces({ MediaType.APPLICATION_JSON, "application/javascript" })
    public ApiResponse getCredentials(@Context UriInfo ui,
            @QueryParam("callback") @DefaultValue("callback") String callback) throws Exception {

        ApiResponse response = createApiResponse();
        response.setAction("get organization client credentials");

        ClientCredentialsInfo keys = new ClientCredentialsInfo(
                management.getClientIdForOrganization(organization.getUuid()),
                management.getClientSecretForOrganization(organization.getUuid()));

        response.setCredentials(keys);
        return response;
    }

    @RequireOrganizationAccess
    @POST
    @Path("credentials")
    @JSONP
    @Produces({ MediaType.APPLICATION_JSON, "application/javascript" })
    public ApiResponse generateCredentials(@Context UriInfo ui,
            @QueryParam("callback") @DefaultValue("callback") String callback) throws Exception {

        ApiResponse response = createApiResponse();
        response.setAction("generate organization client credentials");

        ClientCredentialsInfo credentials = new ClientCredentialsInfo(
                management.getClientIdForOrganization(organization.getUuid()),
                management.newClientSecretForOrganization(organization.getUuid()));

        response.setCredentials(credentials);
        return response;
    }

    public OrganizationInfo getOrganization() {
        return organization;
    }

    @RequireOrganizationAccess
    @Consumes(MediaType.APPLICATION_JSON)
    @PUT
    @JSONP
    @Produces({ MediaType.APPLICATION_JSON, "application/javascript" })
    public ApiResponse executePut(@Context UriInfo ui, Map<String, Object> json,
            @QueryParam("callback") @DefaultValue("callback") String callback) throws Exception {

        if (logger.isTraceEnabled()) {
            logger.trace("executePut");
        }

        ApiResponse response = createApiResponse();
        response.setAction("put");

        response.setParams(ui.getQueryParameters());

        Map customProperties = (Map) json.get(OrganizationsResource.ORGANIZATION_PROPERTIES);
        organization.setProperties(customProperties);
        management.updateOrganization(organization);

        return response;
    }

    @POST
    @Path("export")
    @Consumes(APPLICATION_JSON)
    @RequireOrganizationAccess
    public Response exportPostJson(@Context UriInfo ui, Map<String, Object> json,
            @QueryParam("callback") @DefaultValue("") String callback) throws OAuthSystemException {

        if (logger.isTraceEnabled()) {
            logger.trace("executePostJson");
        }

        Map<String, String> uuidRet = new HashMap<>();

        try {
            Object propertiesObj = json.get("properties");
            if (propertiesObj == null) {
                throw new NullArgumentException("Could not find 'properties'");
            }
            if (!(propertiesObj instanceof Map)) {
                throw new IllegalArgumentException("'properties' not a map");
            }

            @SuppressWarnings("unchecked")
            Map<String, Object> properties = (Map<String, Object>) propertiesObj;

            String storage_provider = (String) properties.get("storage_provider");
            if (storage_provider == null) {
                throw new NullArgumentException("Could not find field 'storage_provider'");
            }

            Object storageInfoObj = properties.get("storage_info");
            if (storageInfoObj == null) {
                throw new NullArgumentException("Could not find field 'storage_info'");
            }
            @SuppressWarnings("unchecked")
            Map<String, Object> storage_info = (Map<String, Object>) storageInfoObj;

            String bucketName = (String) storage_info.get("bucket_location");
            String accessId = (String) storage_info.get("s3_access_id");
            String secretKey = (String) storage_info.get("s3_key");

            if (bucketName == null) {
                throw new NullArgumentException("Could not find field 'bucketName'");
            }
            if (accessId == null) {
                throw new NullArgumentException("Could not find field 's3_access_id'");
            }
            if (secretKey == null) {

                throw new NullArgumentException("Could not find field 's3_key'");
            }

            json.put("organizationId", organization.getUuid());

            UUID jobUUID = exportService.schedule(json);
            uuidRet.put("Export Entity", jobUUID.toString());
        } catch (NullArgumentException e) {
            return Response.status(SC_BAD_REQUEST).type(JSONPUtils.jsonMediaType(callback))
                    .entity(ServiceResource.wrapWithCallback(e.getMessage(), callback)).build();
        } catch (Exception e) {
            //TODO:throw descriptive error message and or include on in the response
            //TODO:fix below, it doesn't work if there is an exception. Make it look like the OauthResponse.
            return Response.status(SC_INTERNAL_SERVER_ERROR).type(JSONPUtils.jsonMediaType(callback))
                    .entity(ServiceResource.wrapWithCallback(e.getMessage(), callback)).build();
        }
        return Response.status(SC_ACCEPTED).entity(uuidRet).build();
    }

    @GET
    @RequireOrganizationAccess
    @Path("export/{exportEntity: [A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}}")
    public Response exportGetJson(@Context UriInfo ui, @PathParam("exportEntity") UUID exportEntityUUIDStr,
            @QueryParam("callback") @DefaultValue("") String callback) throws Exception {

        Export entity;
        try {
            entity = smf.getServiceManager(emf.getManagementAppId()).getEntityManager().get(exportEntityUUIDStr,
                    Export.class);
        } catch (Exception e) { //this might not be a bad request and needs better error checking
            return Response.status(SC_BAD_REQUEST).type(JSONPUtils.jsonMediaType(callback))
                    .entity(ServiceResource.wrapWithCallback(e.getMessage(), callback)).build();
        }

        if (entity == null) {
            return Response.status(SC_BAD_REQUEST).build();
        }

        return Response.status(SC_OK).entity(entity).build();
    }

    protected Set<String> getSetFromCommaSeparatedString(String input) {
        Set<String> ret = new HashSet<>();
        StringTokenizer tokenizer = new StringTokenizer(input, ",");

        while (tokenizer.hasMoreTokens()) {
            ret.add(tokenizer.nextToken());
        }

        return ret;
    }

    protected Map<String, Object> getConfigData(OrganizationConfig orgConfig, String itemsParam,
            boolean includeDefaults, boolean includeOverrides) {
        boolean itemsParamEmpty = itemsParam == null || itemsParam.isEmpty() || itemsParam.equals("*");
        return orgConfig.getOrgConfigCustomMap(itemsParamEmpty ? null : getSetFromCommaSeparatedString(itemsParam),
                includeDefaults, includeOverrides);
    }

    @JSONP
    @RequireSystemAccess
    @GET
    @Path("config")
    public ApiResponse getConfig(@Context UriInfo ui, @QueryParam("items") @DefaultValue("") String itemsParam,
            @QueryParam("separate_defaults") @DefaultValue("false") boolean separateDefaults,
            @QueryParam("callback") @DefaultValue("callback") String callback) throws Exception {

        if (logger.isTraceEnabled()) {
            logger.trace("Get configuration for organization: {}", organization.getUuid());
        }

        ApiResponse response = createApiResponse();
        response.setAction("get organization configuration");
        //response.setParams(ui.getQueryParameters());

        OrganizationConfig orgConfig = management.getOrganizationConfigByUuid(organization.getUuid());

        if (separateDefaults) {
            response.setProperty("orgConfiguration", getConfigData(orgConfig, itemsParam, false, true));
            response.setProperty("defaults", getConfigData(orgConfig, itemsParam, true, false));
        } else {
            response.setProperty("configuration", getConfigData(orgConfig, itemsParam, true, true));
        }

        return response;
    }

    @RequireSystemAccess
    @Consumes(MediaType.APPLICATION_JSON)
    @JSONP
    @PUT
    @Path("config")
    public ApiResponse putConfig(@Context UriInfo ui, Map<String, Object> json,
            @QueryParam("separate_defaults") @DefaultValue("false") boolean separateDefaults,
            @QueryParam("only_changed") @DefaultValue("false") boolean onlyChanged,
            @QueryParam("callback") @DefaultValue("callback") String callback) throws Exception {

        if (logger.isTraceEnabled()) {
            logger.trace("Put configuration for organization: {}", organization.getUuid());
        }

        ApiResponse response = createApiResponse();
        response.setAction("put organization configuration");
        //response.setParams(ui.getQueryParameters());

        OrganizationConfig orgConfig = management.getOrganizationConfigByUuid(organization.getUuid());

        // validates JSON and throws IllegalArgumentException if invalid
        // exception will be handled up the chain
        orgConfig.addProperties(json, true);

        management.updateOrganizationConfig(orgConfig);

        // refresh orgConfig -- to pick up removed entries and defaults
        orgConfig = management.getOrganizationConfigByUuid(organization.getUuid());

        String itemsToReturn = "";
        if (onlyChanged) {
            itemsToReturn = String.join(",", json.keySet());
        }

        if (separateDefaults) {
            response.setProperty("orgConfiguration", getConfigData(orgConfig, itemsToReturn, false, true));
            response.setProperty("defaults", getConfigData(orgConfig, itemsToReturn, true, false));
        } else {
            response.setProperty("configuration", getConfigData(orgConfig, itemsToReturn, true, true));
        }

        return response;
    }

    /** Delete organization is not yet supported */
    //@RequireSystemAccess
    @DELETE
    public ApiResponse deleteOrganization() throws Exception {
        throw new NotImplementedException();
    }

}