/*
* 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.hise.engine;
import org.apache.commons.lang.Validate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hise.api.HISEEngine;
import org.apache.hise.api.HISEUserDetails;
import org.apache.hise.api.Handler;
import org.apache.hise.api.Sender;
import org.apache.hise.dao.HISEDao;
import org.apache.hise.dao.Job;
import org.apache.hise.lang.TaskDefinition;
import org.apache.hise.runtime.Task;
import org.apache.hise.runtime.TaskEvaluator;
import org.apache.hise.utils.DOMUtils;
import org.apache.hise.utils.XQueryEvaluator;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import javax.xml.namespace.QName;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
public class HISEEngineImpl implements HISEEngine {
private static Log log = LogFactory.getLog(HISEEngineImpl.class);
public final Map<String, QName> tasksMap = new HashMap<String, QName>();
public final Map<QName, TaskInfo> tasks = new HashMap<QName, TaskInfo>();
@Inject
private HISEDao hiseDao;
@Inject
private HISEUserDetails hiseUserDetails;
@Inject
private HISEScheduler hiseScheduler;
public HISEDao getHiseDao() {
return hiseDao;
}
public void setHiseUserDetails(HISEUserDetails hiseUserDetails) {
this.hiseUserDetails = hiseUserDetails;
}
public HISEUserDetails getHiseUserDetails() {
return hiseUserDetails;
}
public void setHiseDao(HISEDao hiseDao) {
this.hiseDao = hiseDao;
}
public HISEScheduler getHiseScheduler() {
return hiseScheduler;
}
public void setHiseScheduler(HISEScheduler hiseScheduler) {
this.hiseScheduler = hiseScheduler;
}
public static QName getCanonicalQName(QName q) {
String ns = q.getNamespaceURI();
ns = ns.endsWith("/") ? ns.substring(0, ns.length() - 1) : ns;
return new QName(ns, q.getLocalPart());
}
public static String tasksKey(Handler handler, QName portType, String operation) {
return "" + handler.getId() + ";" + getCanonicalQName(portType) + ";" + operation;
}
public void registerTask(TaskInfo ti) {
TaskDefinition d = ti.taskDefinition;
String taskKey = HISEEngineImpl.tasksKey(ti.dd.getHandler(), d.getTaskInterface().getPortType(), d.getTaskInterface().getOperation());
log.debug("registering route " + taskKey + " -> " + ti.taskDefinition.getTaskName());
QName taskName = ti.taskDefinition.getTaskName();
if (tasks.containsKey(taskName) || tasksMap.containsKey(taskKey)) {
log.warn("Unable to deploy " + ti + " is already deployed.");
}
tasksMap.put(taskKey, ti.taskDefinition.getTaskName());
tasks.put(ti.taskDefinition.getTaskName(), ti);
log.debug("registered");
}
public TaskDefinition getTaskDefinition(QName taskName) {
Validate.notNull(tasks.get(taskName), "" + taskName + " not found. Deployed tasks: " + tasks.toString());
return tasks.get(taskName).taskDefinition;
}
public QName getTaskName(Handler handler, QName portType, String operation) {
java.util.logging.Logger l;
String key = tasksKey(handler, portType, operation);
QName n = tasksMap.get(key);
Validate.notNull(n, "Task for " + portType + " " + operation + " not found in routing table. Key: " + key);
return n;
}
public static String fetchCreatedBy(Node requestHeader) {
log.debug("header " + DOMUtils.domToString(requestHeader));
XQueryEvaluator e = new XQueryEvaluator();
List r = e.evaluateExpression("declare namespace htd='http://www.example.org/WS-HT'; xs:string(*/htd:initiator)", requestHeader);
return r.size() == 1 ? (String) r.get(0) : "";
}
public Node receive(Handler handler, QName portType, String operation, Element body, Node requestHeader) {
String createdBy = fetchCreatedBy(requestHeader);
QName taskName = getTaskName(handler, portType, operation);
assert(taskName != null);
log.debug("routed " + portType + " " + operation + " -> " + taskName);
TaskDefinition def = getTaskDefinition(taskName);
Task t;
if (def.isNotification()) {
t = Task.createNotification(this, getTaskDefinition(taskName), createdBy, body, requestHeader);
} else {
t = Task.create(this, getTaskDefinition(taskName), createdBy, body, requestHeader);
}
return t.getTaskEvaluator().evaluateApproveResponseHeader();
}
public void receiveNotification(QName notificationName, Node request) {
notificationName = DOMUtils.uniqueQName(notificationName);
log.debug("Receiving notification " + notificationName);
TaskInfo n = tasks.get(notificationName);
Validate.notNull(n, "Can't find notification in registry " + notificationName);
Validate.isTrue(n.taskDefinition.isNotification());
Task.createNotification(this, n.taskDefinition, "", request, TaskEvaluator.defaultHeader());
}
public void sendResponse(QName taskName, Node body, Node epr) {
TaskInfo ti = tasks.get(taskName);
log.debug("sending response for " + taskName + " to " + DOMUtils.domToString(epr) + " body " + DOMUtils.domToString(body) + " " + ti.dd.sender);
Sender c = ti.dd.sender ;
log.debug("result: " + c.invoke(body, epr));
}
public void executeJob(Job job) {
Task t = Task.load(this, job.getTask().getId());
try {
t.setCurrentJob(job);
t.getClass().getMethod(job.getAction() + "JobAction").invoke(t);
} catch (Exception e) {
throw new RuntimeException("timer job failed", e);
}
}
// /**
// * {@inheritDoc}
// */
// public Task createTask(QName taskName, String createdBy, String requestXml) {
//
// Validate.notNull(taskName);
// Validate.notNull(requestXml);
//
// log.info("Creating task: " + taskName + " , createdBy: " + createdBy);
//
// TaskDefinition taskDefinition = getTaskDefinition(taskName);
//
// Task newTask = new Task();
// newTask.init(taskDefinition, createdBy, requestXml);
// return newTask;
// }
// /**
// * {@inheritDoc}
// */
// public List<org.apache.hise.dao.Task> getMyTasks(String personName, TaskTypes taskType, GenericHumanRole genericHumanRole, String workQueue, List<org.apache.hise.dao.Task.Status> statuses,
// String whereClause, String orderByClause, String createdOnClause, Integer maxTasks, Integer offset) {
//
// Person person = null;
//
// EntityManager em = entityManagerFactory.createEntityManager();
// if (workQueue == null) {
// person = new AssigneeDao(em).getPerson(personName);
// }
//
// return new TaskDao(em).getTasks(person, taskType, genericHumanRole, workQueue, statuses,
// whereClause, orderByClause, createdOnClause, maxTasks, offset);
// }
// public Person loadUser(String userId, EntityManager em) {
// return new AssigneeDao(em).getPerson(userId);
// }
}