Package org.apache.uima.ducc.transport.uima.dd.generator

Source Code of org.apache.uima.ducc.transport.uima.dd.generator.DeploymentDescriptorGenerator

/*
* 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.uima.ducc.transport.uima.dd.generator;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.uima.ducc.common.uima.UimaUtils;
import org.apache.uima.ducc.common.utils.DuccLogger;
import org.apache.uima.ducc.common.utils.Utils;
import org.apache.uima.ducc.common.utils.XStreamUtils;
import org.apache.uima.ducc.transport.event.common.IDuccUimaAggregate;
import org.apache.uima.ducc.transport.event.common.IDuccUimaAggregateComponent;
import org.apache.uima.ducc.transport.event.common.IDuccUimaDeployableConfiguration;
import org.apache.uima.ducc.transport.event.common.IDuccUimaDeploymentDescriptor;
import org.apache.uima.resourceSpecifier.factory.UimaASPrimitiveDeploymentDescriptor;
import org.apache.uima.util.XMLInputSource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
* Generates UIMA AS deployment descriptor. Takes in as input implementations of
* IDuccUimaDeployableConfiguration interface creates a DD. Currently two implementations
* of IDuccUimaDeployableConfiguration are supported:
*
* 1) IDuccUimaDeploymentDescriptor - this contains a reference to an existing DD that a
*    user provided when submitting a job. In this case, the code overrides a queue name
*    and a broker url and new descriptors are generated.
*
* 2) IDuccUimaAggregate - this contains a list of delegate components that must first
*    be assembled into UIMA Aggregate descriptor. After generating that descriptor the
*    code generates DD for it.
*/
public class DeploymentDescriptorGenerator {

  private DuccLogger logger; // logger to use
  private String duccComponentName; // DUCC component using this class (JD)
  private String userLogDir;  // where to write both descriptors
 
  public DeploymentDescriptorGenerator(String componentName, DuccLogger logger, String userLogDir) {
    this.logger = logger;
    //  Type of ducc component this is using this class (ex.JD)
    this.duccComponentName = componentName;
    this.userLogDir = userLogDir;
  }
  public String generate(String serializedDeployableConfiguration, String jobId) throws Exception {
    IDuccUimaDeployableConfiguration deployableConfiguration =
        (IDuccUimaDeployableConfiguration)XStreamUtils.unmarshall(serializedDeployableConfiguration);
    return generate(deployableConfiguration, jobId);
  }

  public String getComponentName() {
    return duccComponentName;
  }
 
  /**
   * Generates deployment descriptor for DUCC JPs.
   *
   * @param configuration - deployment configuration for the deployment descriptor
   * @return - absolute path to the generated deployment descriptor
   * @throws Exception - failure
   */
  public String generate(IDuccUimaDeployableConfiguration configuration, String jobId)
      throws Exception {
    String methodName="generate";
    if ( configuration instanceof IDuccUimaDeploymentDescriptor) {
      logger.debug(methodName, null, "DUCC Service Wrapper Generates Deployment Descriptor Based on DD Provided by a User:"+((IDuccUimaDeploymentDescriptor)configuration).getDeploymentDescriptorPath());
      // User provided descriptor is used as a basis for generating the actual DD with overriden
      // Broker URL and queue name.
      return generateDeploymentDescriptor((IDuccUimaDeploymentDescriptor)configuration, jobId);
    } else if ( configuration instanceof IDuccUimaAggregate) {
      logger.debug(methodName, null,"DUCC Service Wrapper Generating UIMA AS Deployment Descriptor");
      // First create UIMA aggregate descriptor and then a deployment descriptor.
      return generateDeploymentDescriptor((IDuccUimaAggregate)configuration, jobId);
    } else throw new Exception("Invalid IDuccUimaDeployableConfiguration. Expected IDuccUimaAggregate or IDuccUimaDeploymentDescriptor, but received "+configuration.getClass().getName());
  }
  /**
   * Writes a given content into a file in a given directory
   *
   * @param content - content in the file
   * @return - absolute path to the file created
   *
   * @throws Exception
   */
  private String writeDDFile(String content, String jobId) throws Exception {
    File dir = new File(userLogDir);
    if ( !dir.exists()) {
      dir.mkdir();
    }
    //  compose the file name from a basename (from ducc.properties), constant (-uima-as.dd-) and PID
    BufferedWriter out = null;
    try {
      //  using PID of the ducc component process in the DD file name
      File file = new File(dir, jobId+"-uima-as-dd-"+Utils.getPID()+".xml");
      out = new BufferedWriter(new FileWriter(file));
      out.write(content);
      out.flush();
      return file.getAbsolutePath();
    } catch( Exception e) {
      throw e;
    } finally {
      if ( out != null ) {
        out.close();
      }
    }
  }
  /**
   * Modifies user provided deployment descriptor by changing queue name and broker URL and
   * writes it to a new deployment descriptor file.
   * 
   * @param dd - user specified deployment descriptor
   * @return - absolute path to the generated deployment descriptor
   * @throws Exception
   */
  public String generateDeploymentDescriptor(IDuccUimaDeploymentDescriptor dd, String jobId) throws Exception {
    //  parse DD into DOM
    Document doc = parse(dd.getDeploymentDescriptorPath());
    //  locate the <inputQueue node within the xml
    NodeList nodes = doc.getElementsByTagName("inputQueue");
    //  should only be one such node
    if ( nodes.getLength() > 0 ) {
       Element element = (Element) nodes.item(0);
       // replace queue name
       element.setAttribute("endpoint", "ducc.jd.queue."+jobId);
       // replace broker URL
       element.setAttribute("brokerURL", System.getProperty("ducc.broker.url"));
    } else {
      throw new Exception("Invalid DD-"+dd.getDeploymentDescriptorPath()+". Missing required element <inputQueue ...");
    }
    //
    //  write the adjusted deployment descriptor to the user log dir where dd2spring will
    //  pick it up from
    //
    return writeDDFile(xml2String(doc), jobId);
  }
  /**
   * Parses xml into DOM
   *
   * @param location - name of the xml file to parse
   * @return DOM
   * @throws Exception
   */
  private Document parse(String location ) throws Exception {
    //  Resolve the descriptor either by name or by location
    XMLInputSource xmlin =
            UimaUtils.getXMLInputSource(location); // this guy does all the magic
    //  Parse the descriptor into DOM
    DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    return db.parse(xmlin.getInputStream());
  }
  /**
   * Serializes Deployment Descriptor from DOM to a String
   * @param xmlDoc - xml to serialize
   * @return - serialized DD
   * @throws Exception
   */
  private String xml2String(Document xmlDoc) throws Exception {
    StringWriter writer = null;
   
    DOMSource domSource = new DOMSource(xmlDoc.getDocumentElement());
    writer = new StringWriter();
   
    StreamResult streamResult = new StreamResult(writer);
    TransformerFactory factory = TransformerFactory.newInstance();
    Transformer transformer = factory.newTransformer();
    transformer.transform(domSource, streamResult);
   
    StringBuffer serializedDD = writer.getBuffer();
    return serializedDD.toString();
  }
  /**
   * Creates and returns absolute path to the UIMA AS deployment descriptor.
   *
   * @param aggregateConfiguration - configuration object containing UIMA aggregate delegate
   *        configuration and overrides.
   *
   * @return - absolute path to the generated deployment descriptor
   * @throws Exception
   */
  private String generateDeploymentDescriptor(IDuccUimaAggregate aggregateConfiguration, String jobId ) throws Exception {
   
    List<String> descriptorPaths = new ArrayList<String>();
    List<List<String>> overrides = new ArrayList<List<String>>();
    for( IDuccUimaAggregateComponent component: aggregateConfiguration.getComponents()) {
      descriptorPaths.add(component.getDescriptor());
      overrides.add(component.getOverrides());
    }
    UimaASPrimitiveDeploymentDescriptor dd =
        UimaUtils.createUimaASDeploymentDescriptor(
            aggregateConfiguration.getName(),
            aggregateConfiguration.getDescription(),
            aggregateConfiguration.getBrokerURL(),
            aggregateConfiguration.getEndpoint()
            aggregateConfiguration.getThreadCount(),
            userLogDir,
            jobId+"-uima-ae-descriptor-"+Utils.getPID()+".xml",
          overrides,
          descriptorPaths.toArray(new String[descriptorPaths.size()])
          );
    return writeDDFile(dd.toXML(), jobId);
  }

}
TOP

Related Classes of org.apache.uima.ducc.transport.uima.dd.generator.DeploymentDescriptorGenerator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.