Subversion Repositories XServices

Rev

Rev 199 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
16 brianR 1
/*
114 brianR 2
 *   Copyright 2013 Brian Rosenberger (Brutex Network)
16 brianR 3
 *
4
 *   Licensed under the Apache License, Version 2.0 (the "License");
5
 *   you may not use this file except in compliance with the License.
6
 *   You may obtain a copy of the License at
7
 *
8
 *       http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 *   Unless required by applicable law or agreed to in writing, software
11
 *   distributed under the License is distributed on an "AS IS" BASIS,
12
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 *   See the License for the specific language governing permissions and
14
 *   limitations under the License.
15
 */
16
 
46 brianR 17
package net.brutex.xservices.ws.impl;
16 brianR 18
 
201 brianR 19
import lombok.extern.slf4j.Slf4j;
199 brianR 20
import net.brutex.xservices.types.*;
21
import net.brutex.xservices.types.alfevent.ALFEventResponseType;
22
import net.brutex.xservices.types.alfevent.ALFEventType;
23
import net.brutex.xservices.types.alfevent.ObjectFactory;
114 brianR 24
import net.brutex.xservices.types.ant.FileSetResource;
199 brianR 25
import net.brutex.xservices.util.EventEmitter;
201 brianR 26
import net.brutex.xservices.util.EventmanagerConfiguration;
17 brianR 27
import net.brutex.xservices.util.RunTask;
46 brianR 28
import net.brutex.xservices.ws.MiscService;
199 brianR 29
import net.brutex.xservices.ws.XServicesFault;
17 brianR 30
import org.apache.tools.ant.taskdefs.HostInfo;
20 brianR 31
import org.apache.tools.ant.taskdefs.Sleep;
18 brianR 32
import org.apache.tools.ant.taskdefs.email.EmailTask;
199 brianR 33
import org.h2.jdbcx.JdbcConnectionPool;
34
import org.quartz.*;
35
import org.quartz.impl.StdSchedulerFactory;
16 brianR 36
 
199 brianR 37
import javax.annotation.Resource;
38
import javax.jws.WebService;
39
import javax.servlet.ServletContext;
40
import javax.xml.bind.JAXBContext;
41
import javax.xml.bind.JAXBElement;
42
import javax.xml.bind.JAXBException;
43
import javax.xml.bind.Marshaller;
44
import javax.xml.ws.WebServiceContext;
45
import javax.xml.ws.handler.MessageContext;
46
import java.io.StringReader;
47
import java.io.StringWriter;
48
import java.math.BigInteger;
49
import java.sql.*;
50
import java.time.Instant;
51
import java.util.Date;
52
import java.util.Enumeration;
53
import java.util.Properties;
54
import java.util.UUID;
201 brianR 55
import java.util.concurrent.atomic.AtomicLong;
199 brianR 56
 
57
import static org.quartz.TriggerBuilder.newTrigger;
58
 
59
 
16 brianR 60
/**
114 brianR 61
 * Implements the web service
46 brianR 62
 *
16 brianR 63
 * @author Brian Rosenberger, bru@brutex.de
64
 */
201 brianR 65
@Slf4j
114 brianR 66
@WebService(targetNamespace="http://ws.xservices.brutex.net", endpointInterface="net.brutex.xservices.ws.MiscService", serviceName="MiscService")
67
public class MiscServiceImpl
199 brianR 68
  implements MiscService {
69
 
70
  @Resource
71
  private WebServiceContext context;
72
    public MiscServiceImpl() throws SchedulerException {
73
    }
74
 
75
    public HostinfoType getHostinfo(String hostname) {
114 brianR 76
    HostInfo info = new HostInfo();
77
    info.setTaskName("HostInfo");
78
    RunTask runner = new RunTask(info);
79
    info.setHost(hostname);
16 brianR 80
 
114 brianR 81
    ReturnCode ret = runner.postTask();
82
    HostinfoType infotype = new HostinfoType(
199 brianR 83
            ret.getProperty("NAME"),
84
            ret.getProperty("DOMAIN"),
85
            ret.getProperty("ADDR4"),
86
            ret.getProperty("ADDR6"));
114 brianR 87
    return infotype;
88
  }
16 brianR 89
 
114 brianR 90
  public ReturnCode getInfo() {
91
    ReturnCode r = new ReturnCode();
92
    r.returnCode = 0;
54 brianR 93
 
114 brianR 94
    Properties props = System.getProperties();
54 brianR 95
 
114 brianR 96
    Enumeration e = props.propertyNames();
199 brianR 97
    while (e.hasMoreElements()) {
98
      String propName = (String) e.nextElement();
54 brianR 99
 
199 brianR 100
      String propValue = (String) props.get(propName);
114 brianR 101
      r.stdOut = (r.stdOut + propName + ": " + propValue + "\n");
102
    }
97 brianR 103
 
114 brianR 104
    return r;
105
  }
18 brianR 106
 
199 brianR 107
  public ReturnCode sendMailSimple(HostConnection mailhost, String from, String tolist, String subject, String message) {
108
    return sendMail(from, from, tolist, "", "", subject, message,
109
            "text/plain", null, mailhost.hostname, mailhost.port,
110
            mailhost.user, mailhost.password, "utf-8", false, false);
114 brianR 111
  }
21 brianR 112
 
199 brianR 113
  public ReturnCode sendMailSimpleWithAttachment(HostConnection mailhost, String from, String tolist, String subject, String message, FileSetResource res) {
114
    return sendMail(from, from, tolist, "", "", subject, message,
115
            "text/plain", res, mailhost.hostname, mailhost.port,
116
            mailhost.user, mailhost.password, "utf-8", false, false);
114 brianR 117
  }
21 brianR 118
 
199 brianR 119
  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) {
120
    return sendMail(from, from, tolist, cclist, bcclist, subject, message,
121
            mimetype.value(), res, mailhost.hostname, mailhost.port,
122
            mailhost.user, mailhost.password, charset, tls, ssl);
114 brianR 123
  }
21 brianR 124
 
114 brianR 125
  public ReturnCode sleep(int minutes, int seconds) {
126
    return sleep(0, minutes, seconds, 0);
127
  }
22 brianR 128
 
114 brianR 129
  public String generateUUID() {
130
    return UUID.randomUUID().toString();
131
  }
22 brianR 132
 
199 brianR 133
  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) {
114 brianR 134
    EmailTask mail = new EmailTask();
135
    mail.setTaskName("Mail");
136
    RunTask runner = new RunTask(mail);
137
    mail.setFrom(from);
138
    mail.setReplyTo(replyto);
139
    mail.setToList(tolist);
140
    mail.setCcList(cclist);
141
    mail.setBccList(bcclist);
142
    mail.setSubject(subject);
143
    mail.setMessage(message);
144
    mail.setMessageMimeType(messagemimetype);
145
    if (attachments != null) {
146
      mail.addFileset(attachments.getAntResource(mail.getProject()));
147
    }
148
    mail.setMailhost(mailhost);
149
    mail.setMailport(mailport);
150
    mail.setUser(user);
151
    mail.setPassword(password);
152
    mail.setCharset(charset);
153
    mail.setSSL(ssl);
154
    mail.setEnableStartTLS(tls);
155
    return runner.postTask();
156
  }
157
 
199 brianR 158
  private ReturnCode sleep(int hours, int minutes, int seconds, int milliseconds) {
114 brianR 159
    Sleep sleep = new Sleep();
160
    sleep.setTaskName("Sleep");
161
    RunTask runner = new RunTask(sleep);
162
    sleep.setHours(hours);
163
    sleep.setMinutes(minutes);
164
    sleep.setSeconds(seconds);
165
    sleep.setMilliseconds(milliseconds);
166
    return runner.postTask();
167
  }
168
 
169
  public RuntimeInfoType getMemory() {
170
    return new RuntimeInfoType();
171
  }
199 brianR 172
 
173
  @Override
174
  public BigInteger lock(String id, String objectId) throws XServicesFault {
175
 
176
 
177
 
178
    final String conString = "jdbc:h2:mem:lockdb;DB_CLOSE_DELAY=10;" +
179
            "INIT=CREATE SCHEMA IF NOT EXISTS brutex\\;" +
180
            // "SET SCHEMA brutex\\;" +
181
            "CREATE SEQUENCE IF NOT EXISTS brutex.btx_sequence1\\;" +
182
            "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);";
183
 
184
    //JdbcConnectionPool cp = JdbcConnectionPool.create(conString, "sa", "");
185
    //cp.setMaxConnections(1);
186
 
187
    Connection con = null;
188
    long rows = 0L;
189
    final long ts = new Date().getTime();
190
    try {
191
      Class.forName("org.h2.Driver"); //Java 1.8
192
      con = DriverManager.getConnection(conString);
193
      PreparedStatement prep = con.prepareStatement(
194
              "SELECT btx_id from brutex.tbl_lock where btx_obj_id=? ORDER BY btx_seq DESC");
195
      prep.setString(1, objectId);
196
 
197
      ResultSet rs = prep.executeQuery();
198
      StringBuffer bf = new StringBuffer();
199
      while (rs.next()) {
200
        //bf.append(rs.getString(1));
201
        rows++;
202
      }
203
      rs.close();
204
 
205
      prep = con.prepareStatement("INSERT INTO brutex.tbl_lock values (NEXT VALUE FOR brutex.btx_sequence1, ?, ?, ?)");
206
      prep.setString(1, id);
207
      prep.setString(2, objectId);
208
      prep.setLong(3, ts);
209
      prep.execute();
210
 
211
      prep = con.prepareStatement("DELETE from brutex.tbl_lock WHERE btx_timestamp < ?");
212
      prep.setLong(1, ts - 10000);
213
      prep.execute();
214
      prep.close();
215
 
216
      con.close();
217
      //System.out.println(bf);
218
    } catch (SQLException | ClassNotFoundException e) {
219
      throw new XServicesFault(e);
220
    }
221
 
222
    return BigInteger.valueOf(rows);
223
  }
224
 
225
  @Override
226
  public ALFEventResponseType mergeALFEvent(ALFEventType event) throws XServicesFault {
227
    final Instant d = Instant.now();
228
    final long ts = d.toEpochMilli();
229
 
201 brianR 230
    //Get Parameters from the Servlet Context
199 brianR 231
    final ServletContext servletContext =
232
            (ServletContext) context.getMessageContext().get(MessageContext.SERVLET_CONTEXT);
201 brianR 233
    final EventmanagerConfiguration conf = (EventmanagerConfiguration) servletContext
234
            .getAttribute(EventmanagerConfiguration.KEY);
235
 
236
    final JdbcConnectionPool pool = (JdbcConnectionPool) servletContext.getAttribute("mdbConnection");
237
    final JdbcConnectionPool fpool = (JdbcConnectionPool) servletContext.getAttribute("fdbConnection");
238
    final AtomicLong egres_counter = (AtomicLong) servletContext.getAttribute("egres_counter");
239
    final AtomicLong ingres_counter = (AtomicLong) servletContext.getAttribute("ingres_counter");
240
    final Scheduler scheduler = (Scheduler) servletContext.getAttribute("scheduler");
241
 
242
    log.trace("Read dbConnection from servlet context: {}", pool);
243
 
199 brianR 244
    //System.out.println("Step 2: " + ChronoUnit.MILLIS.between(Instant.now(), d));
245
    final ObjectFactory of = new ObjectFactory();
246
 
247
    final String objectId = event.getBase().getObjectId();
248
    final String eventId = event.getBase().getEventId();
249
    final String objectType = event.getBase().getObjectType();
250
    final String eventType = event.getBase().getEventType();
201 brianR 251
    log.debug("Event id '{}', type '{}' received for object '{}' with object_id '{}'.",
252
            eventId, eventType, objectType, objectId);
199 brianR 253
 
254
    final String mergeStatememt = "MERGE INTO brutex.tbl_events " +
255
            "KEY (btx_event_type, btx_obj_type, btx_obj_id) " +
201 brianR 256
            "VALUES (?,?,?,?,?,?);";
199 brianR 257
 
201 brianR 258
 
199 brianR 259
    try {
260
      Marshaller m = JAXBContext.newInstance(ALFEventType.class).createMarshaller();
261
      m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
262
      m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
263
      JAXBElement<ALFEventType> e = of.createEventNotice(event);
264
      StringWriter sw = new StringWriter();
265
      m.marshal(e, sw);
266
      StringBuilder sb = new StringBuilder();
201 brianR 267
      sb.append(" <soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
268
                "xmlns:ns=\"http://www.eclipse.org/alf/schema/EventBase/1\">\n");
199 brianR 269
      sb.append("<soapenv:Body>\n");
270
      sb.append("<ns:EventNotice>\n");
271
      sb.append(sw);
272
      sb.append("</ns:EventNotice>\n");
273
      sb.append("</soapenv:Body>");
274
      sb.append("</soapenv:Envelope>");
201 brianR 275
 
199 brianR 276
      Connection con = pool.getConnection();
277
      PreparedStatement prep = con.prepareStatement(mergeStatememt);
278
      prep.setString(1, eventType);
279
      prep.setString(2, eventId);
280
      prep.setString(3, objectType);
281
      prep.setString(4, objectId);
282
      prep.setLong(5, ts);
283
      prep.setClob(6, new StringReader(sb.toString()));
284
      prep.execute();
285
      con.commit();
286
      con.close();
287
 
201 brianR 288
      ingres_counter.incrementAndGet();
199 brianR 289
 
290
      synchronized (scheduler) {
291
          if (!scheduler.checkExists(JobKey.jobKey("ALFEmitter"))) {
292
            JobDetail job2 = JobBuilder.newJob(EventEmitter.class)
201 brianR 293
                    .withIdentity("ALFEmitter")
294
                    .build();
295
            job2.getJobDataMap().put("mdbConnection", pool);
296
            job2.getJobDataMap().put("fdbConnection", fpool);
297
            job2.getJobDataMap().put("run_key", ts);
298
            job2.getJobDataMap().put("egres_counter", egres_counter);
299
            job2.getJobDataMap().put("ingres_counter", ingres_counter);
199 brianR 300
 
201 brianR 301
            job2.getJobDataMap().put(EventmanagerConfiguration.KEY, conf);
302
 
199 brianR 303
            SimpleTrigger t = (SimpleTrigger) newTrigger()
201 brianR 304
                    .withIdentity("ALFEmitter").startAt(Date.from(d.plusSeconds(conf.getInterval())))
199 brianR 305
                    .build();
306
 
307
            scheduler.scheduleJob(job2, t);
201 brianR 308
          }
199 brianR 309
      }
310
    } catch (JAXBException | SQLException | SchedulerException e) {
201 brianR 311
        log.error(e.getMessage());
312
        throw new XServicesFault(e);
199 brianR 313
    }
314
    return of.createALFEventResponseType();
315
  }
114 brianR 316
}