org.wso2.carbon.es.migration.client.ProviderMigrationClient.java Source code

Java tutorial

Introduction

Here is the source code for org.wso2.carbon.es.migration.client.ProviderMigrationClient.java

Source

/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* Licensed 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.wso2.carbon.es.migration.client;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.util.AXIOMUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.es.migration.EsMigrationException;
import org.wso2.carbon.es.migration.client.internal.ServiceHolder;
import org.wso2.carbon.es.migration.util.Constants;
import org.wso2.carbon.registry.core.Collection;
import org.wso2.carbon.registry.core.Registry;
import org.wso2.carbon.registry.core.Resource;
import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.core.utils.RegistryUtils;
import org.wso2.carbon.user.api.Tenant;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.core.tenant.TenantManager;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLStreamException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

/*
 * This class perform a migration process to remove "provider" child from the resource content
 * (resources which does not contain a provider attribute in the rxt definition.)
 */
public class ProviderMigrationClient implements MigrationClient {
    private static final Log log = LogFactory.getLog(ProviderMigrationClient.class);

    @Override
    public void cleanOldResources() throws EsMigrationException {
        log.info("Not implemeted for provider migration client. ");
    }

    @Override
    public void databaseMigration() throws EsMigrationException {
        log.info("Not implemeted for provider migration client. ");
    }

    @Override
    public void registryResourceMigration() throws EsMigrationException {
        providerMigration();
    }

    /*
     * This method is used to handle the migration process
     */
    private void providerMigration() throws EsMigrationException {
        long startTimeMillis = System.currentTimeMillis();
        log.info("Provider migration client started");
        try {
            List<Tenant> tenantsArray = getTenantsArray();
            for (Tenant tenant : tenantsArray) {
                migrate(tenant);
            }
            log.info(
                    "Migration Completed Successfully in " + (System.currentTimeMillis() - startTimeMillis) + "ms");
        } catch (IOException e) {
            String msg = "Error occurred while performing operations on input source. ";
            throw new EsMigrationException(msg, e);
        } catch (UserStoreException e) {
            String msg = "Error occurred while searching for tenant admin. ";
            throw new EsMigrationException(msg, e);
        } catch (RegistryException e) {
            String msg = "Error occurred while performing registry operation. ";
            throw new EsMigrationException(msg, e);
        } catch (TransformerException e) {
            String msg = "Error occurred while converting DOM objects into xml string. ";
            throw new EsMigrationException(msg, e);
        } catch (SAXException e) {
            String msg = "Error occurred while parsing the xml content into DOM objects. ";
            throw new EsMigrationException(msg, e);
        } catch (ParserConfigurationException e) {
            String msg = "Error occurred while defining document builder. ";
            throw new EsMigrationException(msg, e);
        } catch (XMLStreamException e) {
            String msg = "Error while processing string to xml";
            throw new EsMigrationException(msg, e);
        } catch (Exception e) {
            String msg = "Error while provider migration. ";
            throw new EsMigrationException(msg, e);
        }
    }

    /*
     * This method is used to get all tenants as a tenant array
     */
    private List<Tenant> getTenantsArray() throws UserStoreException {
        TenantManager tenantManager = ServiceHolder.getRealmService().getTenantManager();
        List<Tenant> tenantsArray = new ArrayList<Tenant>(Arrays.asList(tenantManager.getAllTenants()));
        Tenant superTenant = new Tenant();
        superTenant.setDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
        superTenant.setId(MultitenantConstants.SUPER_TENANT_ID);
        tenantsArray.add(superTenant);
        return tenantsArray;
    }

    /*
     * This method is used to handle the migration process
     */
    private void migrate(Tenant tenant) throws UserStoreException, RegistryException, SAXException,
            TransformerException, ParserConfigurationException, IOException, XMLStreamException {
        int tenantId = tenant.getId();
        try {
            PrivilegedCarbonContext.startTenantFlow();
            PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenant.getDomain(), true);
            PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId);
            String adminName = ServiceHolder.getRealmService().getTenantUserRealm(tenantId).getRealmConfiguration()
                    .getAdminUserName();
            PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(adminName);
            ServiceHolder.getTenantRegLoader().loadTenantRegistry(tenantId);
            Registry registry = ServiceHolder.getRegistryService().getRegistry(adminName, tenantId);
            Collection resourceTypes = (Collection) registry.get(Constants.RESOURCETYPES_RXT_PATH);
            String[] resourceTypesRxtPaths = resourceTypes.getChildren();
            for (String resourceTypeRxtPath : resourceTypesRxtPaths) {
                if (!isContentArtifact(resourceTypeRxtPath, registry)) {
                    ServiceHolder.getRXTStoragePathService().addStoragePath(
                            getMediaType(resourceTypeRxtPath, registry),
                            getStoragePath(resourceTypeRxtPath, registry));
                    if (!(getStoragePath(resourceTypeRxtPath, registry).contains("@{overview_provider}"))
                            || !hasOverviewProviderElement(resourceTypeRxtPath, registry)) {
                        String[] storagePathElements = getStoragePath(resourceTypeRxtPath, registry).split("/");
                        String storagePath = Constants.GOV_PATH;
                        for (String storagePathElement : storagePathElements) {
                            if (storagePathElement.startsWith("@")) {
                                break;
                            }
                            if (!storagePathElement.isEmpty()) {
                                storagePath += ("/" + storagePathElement);
                            }
                        }
                        if (registry.resourceExists(storagePath)) {
                            Collection storageCollection = (Collection) registry.get(storagePath);
                            migrateProvider(storageCollection, registry);
                        }
                    }

                }
            }
        } finally {
            PrivilegedCarbonContext.endTenantFlow();
        }
    }

    /*
     * This method is used to check whether the artifact at the given rxt path is a content artifact
     */
    private boolean isContentArtifact(String rxtPath, Registry registry)
            throws RegistryException, IOException, SAXException, ParserConfigurationException {
        Resource artifactRxt = registry.get(rxtPath);
        byte[] rxtContent = (byte[]) artifactRxt.getContent();
        String rxtContentString = RegistryUtils.decodeBytes(rxtContent);
        Document dom = stringToDocument(rxtContentString);
        Element domElement = (Element) dom.getElementsByTagName(Constants.ARTIFACT_TYPE).item(0);
        return domElement.hasAttribute(Constants.FILE_EXTENSION);
    }

    /*
     * This method is used to get the media type of the artifact at the given rxt path
     */
    private String getMediaType(String rxtPath, Registry registry)
            throws RegistryException, IOException, SAXException, ParserConfigurationException {
        Resource artifactRxt = registry.get(rxtPath);
        byte[] rxtContent = (byte[]) artifactRxt.getContent();
        String rxtContentString = RegistryUtils.decodeBytes(rxtContent);
        Document dom = stringToDocument(rxtContentString);
        Element domElement = (Element) dom.getElementsByTagName(Constants.ARTIFACT_TYPE).item(0);
        return domElement.getAttribute(Constants.TYPE);
    }

    /*
     * This method is used to get the storage path of the artifact at the given rxt path
     */
    private String getStoragePath(String rxtPath, Registry registry)
            throws RegistryException, IOException, SAXException, ParserConfigurationException {
        Resource artifactRxt = registry.get(rxtPath);
        byte[] rxtContent = (byte[]) artifactRxt.getContent();
        String rxtContentString = RegistryUtils.decodeBytes(rxtContent);
        Document dom = stringToDocument(rxtContentString);
        Node storagePath = dom.getElementsByTagName(Constants.STORAGE_PATH).item(0);
        return storagePath.getFirstChild().getNodeValue();
    }

    /**
     * This method checks whether there is a provider in the overview table.
     * @param rxtPath path of the rxt file
     * @param registry registry instance
     * @return boolean
     * @throws RegistryException
     * @throws IOException
     * @throws SAXException
     * @throws ParserConfigurationException
     * @throws XMLStreamException
     */
    private boolean hasOverviewProviderElement(String rxtPath, Registry registry)
            throws RegistryException, IOException, SAXException, ParserConfigurationException, XMLStreamException {
        Resource artifactRxt = registry.get(rxtPath);
        byte[] rxtContent = (byte[]) artifactRxt.getContent();
        String rxtContentString = RegistryUtils.decodeBytes(rxtContent);
        OMElement rxtContentOM = AXIOMUtil.stringToOM(rxtContentString);
        OMElement contentElement = rxtContentOM.getFirstChildWithName(new QName(Constants.CONTENT));
        Iterator tableNodes = contentElement.getChildrenWithLocalName(Constants.TABLE);
        while (tableNodes.hasNext()) {
            OMElement tableOMElement = (OMElement) tableNodes.next();
            if ("Overview".equals(tableOMElement.getAttributeValue(new QName(Constants.NAME)))) {
                Iterator fieldNodes = tableOMElement.getChildrenWithLocalName(Constants.FIELD);
                while (fieldNodes.hasNext()) {
                    OMElement fieldElement = (OMElement) fieldNodes.next();
                    OMElement nameElement = fieldElement.getFirstChildWithName(new QName(Constants.NAME));
                    if (nameElement != null) {
                        if ("Provider".equals(nameElement.getText())) {
                            return true;
                        }
                    }
                }
            }
        }

        return false;
    }

    /*
     * This method is used to remove the 'provider' child of 'overview' from the xml content
     */
    private void migrateProvider(Collection root, Registry registry) throws RegistryException, SAXException,
            TransformerException, ParserConfigurationException, IOException {
        String[] childrenPaths = root.getChildren();
        for (String child : childrenPaths) {
            Resource childResource = registry.get(child);
            if (childResource instanceof Collection) {
                migrateProvider((Collection) childResource, registry);
            } else {
                String path = childResource.getPath();
                byte[] configContent = (byte[]) childResource.getContent();
                String contentString = RegistryUtils.decodeBytes(configContent);
                Document dom = stringToDocument(contentString);
                if (dom.getElementsByTagName(Constants.OVERVIEW).getLength() > 0) {
                    Node overview = dom.getElementsByTagName(Constants.OVERVIEW).item(0);
                    NodeList childrenList = overview.getChildNodes();
                    for (int j = 0; j < childrenList.getLength(); j++) {
                        Node node = childrenList.item(j);
                        if (Constants.PROVIDER.equals(node.getNodeName())) {
                            overview.removeChild(node);
                        }
                    }
                    String newContentString = documentToString(dom);
                    byte[] newContentObject = RegistryUtils.encodeString(newContentString);
                    childResource.setContent(newContentObject);
                    registry.put(path, childResource);
                }
            }
        }
    }

    /*
     * This method is used to convert given xml string to Document type
     */
    private Document stringToDocument(String strXml)
            throws ParserConfigurationException, SAXException, IOException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        InputSource is = new InputSource();
        is.setCharacterStream(new StringReader(strXml));
        return builder.parse(is);
    }

    /*
     * This method is used to convert given xml Document to String type
     */
    private String documentToString(Document doc) throws TransformerException {
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer transformer = tf.newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        StringWriter writer = new StringWriter();
        transformer.transform(new DOMSource(doc), new StreamResult(writer));
        return writer.getBuffer().toString();
    }

}