blob: f5c30315d8b92137f4219af7c52cf297ee169172 [file] [log] [blame]
/*******************************************************************************
* 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.ofbiz.service.job;
import java.io.Serializable;
import java.util.Map;
import org.apache.ofbiz.base.util.Assert;
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.service.DispatchContext;
import org.apache.ofbiz.service.GenericRequester;
import org.apache.ofbiz.service.LocalDispatcher;
import org.apache.ofbiz.service.ServiceUtil;
/**
* A generic async-service job.
*/
@SuppressWarnings("serial")
public class GenericServiceJob extends AbstractJob implements Serializable {
public static final String module = GenericServiceJob.class.getName();
protected final transient GenericRequester requester;
protected final transient DispatchContext dctx;
private final String service;
private final Map<String, Object> context;
public GenericServiceJob(DispatchContext dctx, String jobId, String jobName, String service, Map<String, Object> context, GenericRequester req) {
super(jobId, jobName);
Assert.notNull("dctx", dctx);
this.dctx = dctx;
this.service = service;
this.context = context;
this.requester = req;
}
/**
* Invokes the service.
*/
@Override
public void exec() throws InvalidJobException {
if (currentState != State.QUEUED) {
throw new InvalidJobException("Illegal state change");
}
currentState = State.RUNNING;
init();
Throwable thrown = null;
Map<String, Object> result = null;
// no transaction is necessary since runSync handles this
try {
// get the dispatcher and invoke the service via runSync -- will run all ECAs
LocalDispatcher dispatcher = dctx.getDispatcher();
result = dispatcher.runSync(getServiceName(), getContext());
// check for a failure
if (ServiceUtil.isError(result)) {
thrown = new Exception(ServiceUtil.getErrorMessage(result));
}
if (requester != null) {
requester.receiveResult(result);
}
} catch (Throwable t) {
if (requester != null) {
// pass the exception back to the requester.
requester.receiveThrowable(t);
}
thrown = t;
}
if (thrown == null) {
finish(result);
} else {
failed(thrown);
}
}
/**
* Method is called prior to running the service.
*/
protected void init() throws InvalidJobException {
if (Debug.verboseOn()) Debug.logVerbose("Async-Service initializing.", module);
}
/**
* Method is called after the service has finished successfully.
*/
protected void finish(Map<String, Object> result) throws InvalidJobException {
if (currentState != State.RUNNING) {
throw new InvalidJobException("Illegal state change");
}
currentState = State.FINISHED;
if (Debug.verboseOn()) Debug.logVerbose("Async-Service finished.", module);
}
/**
* Method is called when the service fails.
* @param t Throwable
*/
protected void failed(Throwable t) throws InvalidJobException {
if (currentState != State.RUNNING) {
throw new InvalidJobException("Illegal state change");
}
currentState = State.FAILED;
Debug.logError(t, "Async-Service failed.", module);
}
/**
* Gets the context for the service invocation.
* @return Map of name value pairs making up the service context.
*/
protected Map<String, Object> getContext() throws InvalidJobException {
return context;
}
/**
* Gets the name of the service as defined in the definition file.
* @return The name of the service to be invoked.
*/
protected String getServiceName() {
return service;
}
@Override
public boolean isValid() {
return currentState == State.CREATED;
}
@Override
public void deQueue() throws InvalidJobException {
super.deQueue();
throw new InvalidJobException("Unable to queue job [" + getJobId() + "]");
}
}