org.apache.falcon.resource.AbstractExtensionManager.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.falcon.resource.AbstractExtensionManager.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.falcon.resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.falcon.FalconException;
import org.apache.falcon.FalconWebException;
import org.apache.falcon.entity.EntityNotRegisteredException;
import org.apache.falcon.entity.EntityUtil;
import org.apache.falcon.entity.parser.ValidationException;
import org.apache.falcon.extensions.ExtensionStatus;
import org.apache.falcon.entity.v0.EntityType;
import org.apache.falcon.extensions.jdbc.ExtensionMetaStore;
import org.apache.falcon.extensions.store.ExtensionStore;
import org.apache.falcon.persistence.ExtensionBean;
import org.apache.falcon.persistence.ExtensionJobsBean;
import org.apache.falcon.security.CurrentUser;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.core.Response;
import java.util.Collections;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * A base class for managing Extension Operations.
 */
public class AbstractExtensionManager extends AbstractSchedulableEntityManager {
    public static final Logger LOG = LoggerFactory.getLogger(AbstractExtensionManager.class);

    private static final String JOB_NAME = "jobName";
    protected static final String TAG_PREFIX_EXTENSION_JOB = "_falcon_extension_job=";
    private static final String EXTENSION_NAME = "extensionName";
    private static final String FEEDS = "feeds";
    private static final String PROCESSES = "processes";
    private static final String CONFIG = "config";
    private static final String CREATION_TIME = "creationTime";
    private static final String LAST_UPDATE_TIME = "lastUpdatedTime";
    protected static final String ASCENDING_SORT_ORDER = "asc";
    protected static final String DESCENDING_SORT_ORDER = "desc";

    public static final String NAME = "name";
    public static final String STATUS = "status";
    private static final String EXTENSION_TYPE = "type";
    private static final String EXTENSION_DESC = "description";
    private static final String EXTENSION_LOCATION = "location";
    private static final String ENTITY_EXISTS_STATUS = "EXISTS";
    private static final String ENTITY_NOT_EXISTS_STATUS = "NOT_EXISTS";

    protected static void validateExtensionName(final String extensionName) {
        if (StringUtils.isBlank(extensionName)) {
            throw FalconWebException.newAPIException("Extension name is mandatory and shouldn't be blank",
                    Response.Status.BAD_REQUEST);
        }
    }

    protected APIResult registerExtensionMetadata(String extensionName, String path, String description,
            String owner) {
        validateExtensionName(extensionName);
        try {
            return new APIResult(APIResult.Status.SUCCEEDED,
                    ExtensionStore.get().registerExtension(extensionName, path, description, owner));
        } catch (Throwable e) {
            throw FalconWebException.newAPIException(e, Response.Status.INTERNAL_SERVER_ERROR);
        }
    }

    public APIResult getExtensionJobDetail(String jobName) {
        try {
            return new APIResult(APIResult.Status.SUCCEEDED, buildExtensionJobDetailResult(jobName).toString());
        } catch (FalconException e) {
            throw FalconWebException.newAPIException(e, Response.Status.INTERNAL_SERVER_ERROR);
        }
    }

    protected APIResult getExtensionDetail(String extensionName) {
        try {
            return new APIResult(APIResult.Status.SUCCEEDED, buildExtensionDetailResult(extensionName).toString());
        } catch (FalconException e) {
            throw FalconWebException.newAPIException(e, Response.Status.INTERNAL_SERVER_ERROR);
        }
    }

    public APIResult getExtensions() {
        try {
            return new APIResult(APIResult.Status.SUCCEEDED, buildEnumerateResult().toString());
        } catch (FalconException e) {
            throw FalconWebException.newAPIException(e, Response.Status.INTERNAL_SERVER_ERROR);
        }
    }

    public ExtensionJobList getExtensionJobs(String extensionName, String sortOrder, String doAsUser) {
        TreeMap<String, String> jobAndExtensionNames = new TreeMap<>();
        List<ExtensionJobsBean> extensionJobs = null;

        if (StringUtils.isNoneBlank(extensionName)) {
            extensionJobs = ExtensionStore.getMetaStore().getJobsForAnExtension(extensionName);
        } else {
            extensionJobs = ExtensionStore.getMetaStore().getAllExtensionJobs();
        }

        for (ExtensionJobsBean job : extensionJobs) {
            jobAndExtensionNames.put(job.getJobName(), job.getExtensionName());
        }

        sortOrder = (sortOrder == null) ? ASCENDING_SORT_ORDER : sortOrder;
        switch (sortOrder.toLowerCase()) {
        case DESCENDING_SORT_ORDER:
            return new ExtensionJobList(extensionJobs.size(), jobAndExtensionNames.descendingMap());

        default:
            return new ExtensionJobList(extensionJobs.size(), jobAndExtensionNames);
        }
    }

    public APIResult deleteExtensionMetadata(String extensionName) {
        validateExtensionName(extensionName);
        ExtensionStore metaStore = ExtensionStore.get();
        try {
            canDeleteExtension(extensionName);
            return new APIResult(APIResult.Status.SUCCEEDED,
                    metaStore.deleteExtension(extensionName, CurrentUser.getUser()));
        } catch (FalconException e) {
            throw FalconWebException.newAPIException(e);
        }
    }

    private void canDeleteExtension(String extensionName) throws FalconException {
        ExtensionMetaStore metaStore = ExtensionStore.getMetaStore();
        List<ExtensionJobsBean> extensionJobs = metaStore.getJobsForAnExtension(extensionName);
        if (!extensionJobs.isEmpty()) {
            StringBuilder jobs = new StringBuilder();
            for (ExtensionJobsBean extensionJobsBean : extensionJobs) {
                jobs.append("\n" + extensionJobsBean.getJobName());
            }
            LOG.error("Extension:" + extensionName
                    + " cannot be unregistered as following instances are dependent on " + "the extension:"
                    + jobs.toString());
            throw new FalconException(
                    "Extension:" + extensionName + " cannot be unregistered as following instances"
                            + " are dependent on the extension:" + jobs.toString());
        }
    }

    protected SortedMap<EntityType, List<String>> getJobEntities(ExtensionJobsBean extensionJobsBean)
            throws FalconException {
        TreeMap<EntityType, List<String>> entityMap = new TreeMap<>(Collections.<EntityType>reverseOrder());
        entityMap.put(EntityType.PROCESS, extensionJobsBean.getProcesses());
        entityMap.put(EntityType.FEED, extensionJobsBean.getFeeds());
        return entityMap;
    }

    private JSONObject buildExtensionJobDetailResult(final String jobName) throws FalconException {
        ExtensionMetaStore metaStore = ExtensionStore.getMetaStore();
        ExtensionJobsBean jobsBean = metaStore.getExtensionJobDetails(jobName);
        if (jobsBean == null) {
            throw new ValidationException("Job name not found:" + jobName);
        }
        ExtensionBean extensionBean = metaStore.getDetail(jobsBean.getExtensionName());
        JSONObject detailsObject = new JSONObject();
        try {
            detailsObject.put(JOB_NAME, jobsBean.getJobName());
            detailsObject.put(EXTENSION_NAME, jobsBean.getExtensionName());
            detailsObject.put(FEEDS, getEntitiesStatus(jobsBean.getFeeds(), EntityType.FEED));
            detailsObject.put(PROCESSES, getEntitiesStatus(jobsBean.getProcesses(), EntityType.PROCESS));
            detailsObject.put(CONFIG, jobsBean.getConfig());
            detailsObject.put(CREATION_TIME, jobsBean.getCreationTime());
            detailsObject.put(LAST_UPDATE_TIME, jobsBean.getLastUpdatedTime());
            detailsObject.put(EXTENSION_LOCATION, extensionBean.getLocation());
            detailsObject.put(EXTENSION_TYPE, extensionBean.getExtensionType());
        } catch (JSONException e) {
            LOG.error("Exception while building extension jon details for job {}", jobName, e);
        }
        return detailsObject;
    }

    public static String getJobNameFromTag(String tags) {
        int nameStart = tags.indexOf(TAG_PREFIX_EXTENSION_JOB);
        if (nameStart == -1) {
            return null;
        }

        nameStart = nameStart + TAG_PREFIX_EXTENSION_JOB.length();
        int nameEnd = tags.indexOf(',', nameStart);
        if (nameEnd == -1) {
            nameEnd = tags.length();
        }
        return tags.substring(nameStart, nameEnd);
    }

    protected String disableExtension(String extensionName, String currentUser) {
        validateExtensionName(extensionName);
        try {
            return ExtensionStore.get().updateExtensionStatus(extensionName, currentUser, ExtensionStatus.DISABLED);
        } catch (Throwable e) {
            throw FalconWebException.newAPIException(e, Response.Status.INTERNAL_SERVER_ERROR);
        }
    }

    protected String enableExtension(String extensionName, String currentUser) {
        validateExtensionName(extensionName);
        try {
            return ExtensionStore.get().updateExtensionStatus(extensionName, currentUser, ExtensionStatus.ENABLED);
        } catch (Throwable e) {
            throw FalconWebException.newAPIException(e, Response.Status.INTERNAL_SERVER_ERROR);
        }
    }

    private JSONObject buildExtensionDetailResult(final String extensionName) throws FalconException {
        ExtensionMetaStore metaStore = ExtensionStore.getMetaStore();

        if (!metaStore.checkIfExtensionExists(extensionName)) {
            throw new ValidationException("No extension resources found for " + extensionName);
        }

        ExtensionBean extensionBean = metaStore.getDetail(extensionName);
        if (extensionBean == null) {
            LOG.error("Extension not found: " + extensionName);
            throw new FalconException("Extension not found:" + extensionName);
        }
        JSONObject resultObject = new JSONObject();
        try {
            resultObject.put(NAME, extensionBean.getExtensionName());
            resultObject.put(EXTENSION_TYPE, extensionBean.getExtensionType());
            resultObject.put(EXTENSION_DESC, extensionBean.getDescription());
            resultObject.put(EXTENSION_LOCATION, extensionBean.getLocation());
        } catch (JSONException e) {
            LOG.error("Exception in buildDetailResults:", e);
            throw new FalconException(e);
        }
        return resultObject;
    }

    private static JSONArray buildEnumerateResult() throws FalconException {
        JSONArray results = new JSONArray();
        ExtensionMetaStore metaStore = ExtensionStore.getMetaStore();
        List<ExtensionBean> extensionBeanList = metaStore.getAllExtensions();
        for (ExtensionBean extensionBean : extensionBeanList) {
            JSONObject resultObject = new JSONObject();

            try {
                resultObject.put(NAME, extensionBean.getExtensionName().toLowerCase());
                resultObject.put(EXTENSION_TYPE, extensionBean.getExtensionType());
                resultObject.put(EXTENSION_DESC, extensionBean.getDescription());
                resultObject.put(EXTENSION_LOCATION, extensionBean.getLocation());
            } catch (JSONException e) {
                throw new FalconException(e);
            }
            results.put(resultObject);
        }
        return results;
    }

    protected static void checkIfExtensionIsEnabled(String extensionName) {
        ExtensionBean extensionBean = getExtensionIfExists(extensionName);
        if (!extensionBean.getStatus().equals(ExtensionStatus.ENABLED)) {
            LOG.error("Extension: " + extensionName + " is in disabled state.");
            throw FalconWebException.newAPIException("Extension: " + extensionName + " is in disabled state.",
                    Response.Status.INTERNAL_SERVER_ERROR);
        }
    }

    protected static ExtensionBean getExtensionIfExists(String extensionName) {
        ExtensionMetaStore metaStore = ExtensionStore.getMetaStore();
        ExtensionBean extensionBean = metaStore.getDetail(extensionName);
        if (extensionBean == null) {
            LOG.error("Extension not found: " + extensionName);
            throw FalconWebException.newAPIException("Extension not found:" + extensionName,
                    Response.Status.NOT_FOUND);
        }
        return extensionBean;
    }

    protected static void checkIfExtensionJobNameExists(String jobName, String extensionName) {
        ExtensionMetaStore metaStore = ExtensionStore.getMetaStore();
        ExtensionJobsBean extensionJobsBean = metaStore.getExtensionJobDetails(jobName);
        if (extensionJobsBean != null && !extensionJobsBean.getExtensionName().equals(extensionName)) {
            LOG.error("Extension job with name: " + extensionName + " already exists.");
            throw FalconWebException.newAPIException("Extension job with name: " + jobName + " already exists.",
                    Response.Status.INTERNAL_SERVER_ERROR);
        }
    }

    private JSONArray getEntitiesStatus(List<String> entities, EntityType type)
            throws JSONException, FalconException {
        JSONArray entityObjects = new JSONArray();
        for (String entity : entities) {
            JSONObject entityObject = new JSONObject();
            try {
                entityObject.put(NAME, entity);
                EntityUtil.getEntity(type, entity);
                entityObject.put(STATUS, ENTITY_EXISTS_STATUS);
            } catch (EntityNotRegisteredException e) {
                entityObject.put(STATUS, ENTITY_NOT_EXISTS_STATUS);
            }
            entityObjects.put(entityObject);
        }
        return entityObjects;
    }
}