Subversion Repositories XServices

Rev

Rev 198 | Rev 201 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

/*
 *   Copyright 2013 Brian Rosenberger (Brutex Network)
 *
 *   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 net.brutex.xservices.ws.impl;

import net.brutex.xservices.types.*;
import net.brutex.xservices.types.alfevent.ALFEventResponseType;
import net.brutex.xservices.types.alfevent.ALFEventType;
import net.brutex.xservices.types.alfevent.ObjectFactory;
import net.brutex.xservices.types.ant.FileSetResource;
import net.brutex.xservices.util.EventEmitter;
import net.brutex.xservices.util.RunTask;
import net.brutex.xservices.ws.MiscService;
import net.brutex.xservices.ws.XServicesFault;
import org.apache.tools.ant.taskdefs.HostInfo;
import org.apache.tools.ant.taskdefs.Sleep;
import org.apache.tools.ant.taskdefs.email.EmailTask;
import org.h2.jdbcx.JdbcConnectionPool;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import javax.annotation.Resource;
import javax.jws.WebService;
import javax.servlet.ServletContext;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
import java.io.StringReader;
import java.io.StringWriter;
import java.math.BigInteger;
import java.sql.*;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.Enumeration;
import java.util.Properties;
import java.util.UUID;

import static org.quartz.TriggerBuilder.newTrigger;


/**
 * Implements the web service
 * 
 * @author Brian Rosenberger, bru@brutex.de
 */
@WebService(targetNamespace="http://ws.xservices.brutex.net", endpointInterface="net.brutex.xservices.ws.MiscService", serviceName="MiscService")
public class MiscServiceImpl
  implements MiscService {

  @Resource
  private WebServiceContext context;

  // Grab the Scheduler instance from the Factory
  private final Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
  private final static String conStr = "jdbc:h2:mem:lockdb;DB_CLOSE_DELAY=-1;";

  private final static String dbinit = "" +
          "CREATE SCHEMA IF NOT EXISTS brutex;" +
          "CREATE TABLE IF NOT EXISTS brutex.tbl_events (" +
          "btx_event_type VARCHAR(128) NOT NULL," +
          "btx_id VARCHAR(32) NOT NULL, " +
          "btx_obj_type VARCHAR(32) NOT NULL, " +
          "btx_obj_id VARCHAR(32) NOT NULL, " +
          "btx_timestamp BIGINT NOT NULL," +
          "btx_event CLOB" +
          ");" +
          "CREATE INDEX IF NOT EXISTS brutex.btx_idx ON brutex.tbl_events (btx_obj_id, btx_obj_type, btx_event_type);" +
          "CREATE INDEX IF NOT EXISTS brutex.IDX_TO_DESC ON brutex.tbl_events (btx_timestamp ASC);";

    public MiscServiceImpl() throws SchedulerException {
    }

    public HostinfoType getHostinfo(String hostname) {
    HostInfo info = new HostInfo();
    info.setTaskName("HostInfo");
    RunTask runner = new RunTask(info);
    info.setHost(hostname);

    ReturnCode ret = runner.postTask();
    HostinfoType infotype = new HostinfoType(
            ret.getProperty("NAME"),
            ret.getProperty("DOMAIN"),
            ret.getProperty("ADDR4"),
            ret.getProperty("ADDR6"));
    return infotype;
  }

  public ReturnCode getInfo() {
    ReturnCode r = new ReturnCode();
    r.returnCode = 0;

    Properties props = System.getProperties();

    Enumeration e = props.propertyNames();
    while (e.hasMoreElements()) {
      String propName = (String) e.nextElement();

      String propValue = (String) props.get(propName);
      r.stdOut = (r.stdOut + propName + ": " + propValue + "\n");
    }

    return r;
  }

  public ReturnCode sendMailSimple(HostConnection mailhost, String from, String tolist, String subject, String message) {
    return sendMail(from, from, tolist, "", "", subject, message,
            "text/plain", null, mailhost.hostname, mailhost.port,
            mailhost.user, mailhost.password, "utf-8", false, false);
  }

  public ReturnCode sendMailSimpleWithAttachment(HostConnection mailhost, String from, String tolist, String subject, String message, FileSetResource res) {
    return sendMail(from, from, tolist, "", "", subject, message,
            "text/plain", res, mailhost.hostname, mailhost.port,
            mailhost.user, mailhost.password, "utf-8", false, false);
  }

  public ReturnCode sendMail(HostConnection mailhost, String from, String tolist, String cclist, String bcclist, String subject, MailMimeType mimetype, String charset, String message, FileSetResource res, boolean ssl, boolean tls) {
    return sendMail(from, from, tolist, cclist, bcclist, subject, message,
            mimetype.value(), res, mailhost.hostname, mailhost.port,
            mailhost.user, mailhost.password, charset, tls, ssl);
  }

  public ReturnCode sleep(int minutes, int seconds) {
    return sleep(0, minutes, seconds, 0);
  }

  public String generateUUID() {
    return UUID.randomUUID().toString();
  }

  private ReturnCode sendMail(String from, String replyto, String tolist, String cclist, String bcclist, String subject, String message, String messagemimetype, FileSetResource attachments, String mailhost, int mailport, String user, String password, String charset, boolean tls, boolean ssl) {
    EmailTask mail = new EmailTask();
    mail.setTaskName("Mail");
    RunTask runner = new RunTask(mail);
    mail.setFrom(from);
    mail.setReplyTo(replyto);
    mail.setToList(tolist);
    mail.setCcList(cclist);
    mail.setBccList(bcclist);
    mail.setSubject(subject);
    mail.setMessage(message);
    mail.setMessageMimeType(messagemimetype);
    if (attachments != null) {
      mail.addFileset(attachments.getAntResource(mail.getProject()));
    }
    mail.setMailhost(mailhost);
    mail.setMailport(mailport);
    mail.setUser(user);
    mail.setPassword(password);
    mail.setCharset(charset);
    mail.setSSL(ssl);
    mail.setEnableStartTLS(tls);
    return runner.postTask();
  }

  private ReturnCode sleep(int hours, int minutes, int seconds, int milliseconds) {
    Sleep sleep = new Sleep();
    sleep.setTaskName("Sleep");
    RunTask runner = new RunTask(sleep);
    sleep.setHours(hours);
    sleep.setMinutes(minutes);
    sleep.setSeconds(seconds);
    sleep.setMilliseconds(milliseconds);
    return runner.postTask();
  }

  public RuntimeInfoType getMemory() {
    return new RuntimeInfoType();
  }

  @Override
  public BigInteger lock(String id, String objectId) throws XServicesFault {



    final String conString = "jdbc:h2:mem:lockdb;DB_CLOSE_DELAY=10;" +
            "INIT=CREATE SCHEMA IF NOT EXISTS brutex\\;" +
            // "SET SCHEMA brutex\\;" +
            "CREATE SEQUENCE IF NOT EXISTS brutex.btx_sequence1\\;" +
            "CREATE TABLE IF NOT EXISTS brutex.tbl_lock (btx_seq BIGINT NOT NULL, btx_id VARCHAR(100) NOT NULL, btx_obj_id VARCHAR(100) NOT NULL, btx_timestamp BIGINT NOT NULL);";

    //JdbcConnectionPool cp = JdbcConnectionPool.create(conString, "sa", "");
    //cp.setMaxConnections(1);

    Connection con = null;
    long rows = 0L;
    final long ts = new Date().getTime();
    try {
      Class.forName("org.h2.Driver"); //Java 1.8
      con = DriverManager.getConnection(conString);
      PreparedStatement prep = con.prepareStatement(
              "SELECT btx_id from brutex.tbl_lock where btx_obj_id=? ORDER BY btx_seq DESC");
      prep.setString(1, objectId);

      ResultSet rs = prep.executeQuery();
      StringBuffer bf = new StringBuffer();
      while (rs.next()) {
        //bf.append(rs.getString(1));
        rows++;
      }
      rs.close();

      prep = con.prepareStatement("INSERT INTO brutex.tbl_lock values (NEXT VALUE FOR brutex.btx_sequence1, ?, ?, ?)");
      prep.setString(1, id);
      prep.setString(2, objectId);
      prep.setLong(3, ts);
      prep.execute();

      prep = con.prepareStatement("DELETE from brutex.tbl_lock WHERE btx_timestamp < ?");
      prep.setLong(1, ts - 10000);
      prep.execute();
      prep.close();

      con.close();
      //System.out.println(bf);
    } catch (SQLException | ClassNotFoundException e) {
      throw new XServicesFault(e);
    }

    return BigInteger.valueOf(rows);
  }

  @Override
  public ALFEventResponseType mergeALFEvent(ALFEventType event) throws XServicesFault {
    final Instant d = Instant.now();
    final long ts = d.toEpochMilli();
    //System.out.println("Step 1: " + ChronoUnit.MILLIS.between(Instant.now(), d));

    final ServletContext servletContext =
            (ServletContext) context.getMessageContext().get(MessageContext.SERVLET_CONTEXT);
    final JdbcConnectionPool pool = (JdbcConnectionPool) servletContext.getAttribute("dbConnection");
    //System.out.println("Step 2: " + ChronoUnit.MILLIS.between(Instant.now(), d));
    final ObjectFactory of = new ObjectFactory();

    final String objectId = event.getBase().getObjectId();
    final String eventId = event.getBase().getEventId();
    final String objectType = event.getBase().getObjectType();
    final String eventType = event.getBase().getEventType();

    final String mergeStatememt = "MERGE INTO brutex.tbl_events " +
            "KEY (btx_event_type, btx_obj_type, btx_obj_id) " +
            "VALUES (?,?,?,?,?,?) " +
            "";

    long rows = 0L;
    //System.out.println("Step 3: " + ChronoUnit.MILLIS.between(Instant.now(), d));
    try {
      //System.out.println("Step 4: " + ChronoUnit.MILLIS.between(Instant.now(), d));
      Marshaller m = JAXBContext.newInstance(ALFEventType.class).createMarshaller();
      m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
      m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
      JAXBElement<ALFEventType> e = of.createEventNotice(event);
      StringWriter sw = new StringWriter();
      m.marshal(e, sw);
      StringBuilder sb = new StringBuilder();
      sb.append(" <soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns=\"http://www.eclipse.org/alf/schema/EventBase/1\">\n");
      sb.append("<soapenv:Body>\n");
      sb.append("<ns:EventNotice>\n");
      sb.append(sw);
      sb.append("</ns:EventNotice>\n");
      sb.append("</soapenv:Body>");
      sb.append("</soapenv:Envelope>");
      //System.out.println("Step 5: " + ChronoUnit.MILLIS.between(Instant.now(), d));
      Connection con = pool.getConnection();
      //System.out.println("Step 6: " + ChronoUnit.MILLIS.between(Instant.now(), d));
      PreparedStatement prep = con.prepareStatement(mergeStatememt);
      prep.setString(1, eventType);
      prep.setString(2, eventId);
      prep.setString(3, objectType);
      prep.setString(4, objectId);
      prep.setLong(5, ts);
      prep.setClob(6, new StringReader(sb.toString()));
      //prep.setLong(7, ts-20000);
      //System.out.println("Step 7 SQL START: " + ChronoUnit.MILLIS.between(Instant.now(), d));
      prep.execute();
      con.commit();
      con.close();
      //System.out.println("Step 8 SQL END: " + ChronoUnit.MILLIS.between(Instant.now(), d));
      //SimpleSoap ss = new SimpleSoap("http://localhost:8099/ALFEventManager/services/ALFEventManagerSOAP", sb.toString());
      //ss.sendSoap(false);


      // and start it off

      if (!scheduler.isStarted())
        scheduler.start();
      if (scheduler.isInStandbyMode())
        scheduler.resumeAll();
      //System.out.println("Step 9: " + ChronoUnit.MILLIS.between(Instant.now(), d));
      synchronized (scheduler) {
          if (!scheduler.checkExists(JobKey.jobKey("ALFEmitter"))) {
            JobDetail job2 = JobBuilder.newJob(EventEmitter.class)
                    .withIdentity("ALFEmitter").build();
            //job2.getJobDataMap().put("script", job.getScript());
            //job2.getJobDataMap().put("description", job.getDescription());
            //job2.getJobDataMap().put("date", job.getDate());

            SimpleTrigger t = (SimpleTrigger) newTrigger()
                    .withIdentity("ALFEmitter").startAt(Date.from(d.plusSeconds(20)))
                    .build();

            scheduler.scheduleJob(job2, t);
        }
      }
      //System.out.println("Step 10: " + ChronoUnit.MILLIS.between(Instant.now(), d));
    } catch (JAXBException | SQLException | SchedulerException e) {
      throw new XServicesFault(e);
    }
    return of.createALFEventResponseType();
  }
}

Generated by GNU Enscript 1.6.5.90.