initialize
This commit is contained in:
21
interface/cogiscan/plugin/src/main/assembly/descriptor.xml
Normal file
21
interface/cogiscan/plugin/src/main/assembly/descriptor.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||
<id>bin</id>
|
||||
<formats>
|
||||
<format>zip</format>
|
||||
</formats>
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}</directory>
|
||||
<outputDirectory/>
|
||||
<includes>
|
||||
<include>*dependencies*.jar</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>*.zip</exclude>
|
||||
</excludes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.itac.mes.cogiscan;
|
||||
|
||||
public class CogiscanException extends Exception {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -9180600020616111590L;
|
||||
private ResponseDetail responseDetail;
|
||||
|
||||
public CogiscanException(ResponseDetail responseDetail) {
|
||||
this.responseDetail = responseDetail;
|
||||
}
|
||||
|
||||
public ResponseDetail getResponseDetail() {
|
||||
return responseDetail;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.itac.mes.cogiscan;
|
||||
|
||||
public interface CogiscanFields {
|
||||
|
||||
public static final String PLACEMENT_COMPONENT_ID = "placement.componentId";
|
||||
public static final String PLACEMENT_LIST = "placementList";
|
||||
public static final String EVENT_DATE = "eventDate";
|
||||
public static final String STATUS = "status";
|
||||
public static final String MESSAGE_DETAIL = "messageDetail";
|
||||
public static final String MESSAGE_STOP = "messageStop";
|
||||
public static final String MESSAGE_START = "messageStart";
|
||||
public static final String MESSAGE_CODE = "messageCode";
|
||||
public static final String MACHINE_PLACEMENTS = "machinePlacements";
|
||||
public static final String END_PRODUCTION = "endProduction";
|
||||
public static final String START_PRODUCTION = "startProduction";
|
||||
public static final String STATE = "state";
|
||||
public static final String PLACEMENT_RECIPE_NAME = "placementRecipeName";
|
||||
public static final String SERIAL_NUMBER = "serialNumber";
|
||||
public static final String CONTAINER_COMPONENT_ID = "container.componentId";
|
||||
public static final String CONTAINER_CONTAINER_ID = "container.containerId";
|
||||
public static final String OPERATION = "operation";
|
||||
public static final String MACHINE_PLACEMENT_HANDLER_INFO = "machinePlacement.handlerInfo";
|
||||
public static final String PLACEMENT_PANEL_NUMBER = "placement.panelNumber";
|
||||
public static final String PLACEMENT_DESIGNATOR = "placement.designator";
|
||||
public static final String PLACEMENTS = "placements";
|
||||
public static final String HANDLER_ID = "handlerId";
|
||||
public static final String CONTAINER_ID = "containerId";
|
||||
public static final String COMPONENT_ID = "componentId";
|
||||
public static final String CONTAINER = "container";
|
||||
public static final String LANE = "lane";
|
||||
public static final String LINE_NAME = "lineName";
|
||||
public static final String MACHINE_NAME = "machineName";
|
||||
public static final String MACHINE = "machine";
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2016 iTAC Software AG, Germany. All Rights Reserved.
|
||||
*
|
||||
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
|
||||
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
|
||||
* without the written permission of iTAC Software AG.
|
||||
*/
|
||||
package com.itac.mes.cogiscan;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class DateAdapter {
|
||||
|
||||
private static SimpleDateFormat sdf = ((SimpleDateFormat) SimpleDateFormat.getDateTimeInstance());
|
||||
|
||||
static {
|
||||
sdf.applyPattern("yyyy-MM-dd'T'HH:mm:ss.S Z");
|
||||
}
|
||||
|
||||
public static Date parseDate(String s) {
|
||||
try {
|
||||
return sdf.parse(s);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new Date(0);
|
||||
}
|
||||
|
||||
public static String printDate(Date dt) {
|
||||
return sdf.format(dt);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (c) 2016 iTAC Software AG, Germany. All Rights Reserved.
|
||||
*
|
||||
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
|
||||
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
|
||||
* without the written permission of iTAC Software AG.
|
||||
*/
|
||||
package com.itac.mes.cogiscan;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.itac.mes.cogiscan.data.FailoverHost;
|
||||
import com.itac.mes.datainterface.data.IMesServicesLog;
|
||||
|
||||
public class FailoverHostList {
|
||||
|
||||
// this list is cyclically updated as long as a mesService Endpoint is active and not closed
|
||||
private List<FailoverHost> failoverHosts;
|
||||
// this is the host all current calls are going to
|
||||
private FailoverHost activeHost;
|
||||
private IMesServicesLog log;
|
||||
|
||||
/**
|
||||
* @param log
|
||||
* if log is null (which is allowed) simply usse the System. out for logging
|
||||
*/
|
||||
public FailoverHostList(IMesServicesLog log) {
|
||||
super();
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
public IMesServicesLog getLog() {
|
||||
if (log == null) {
|
||||
log = new IMesServicesLog() {
|
||||
|
||||
@Override
|
||||
public void out(String text) {
|
||||
System.out.println(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void err(String text) {
|
||||
System.err.println(text);
|
||||
}
|
||||
};
|
||||
}
|
||||
return log;
|
||||
}
|
||||
|
||||
public void setFailover(List<FailoverHost> newFailoverHosts) {
|
||||
// protokolliren, was sich geändert hat
|
||||
boolean newHosts = false;
|
||||
if (newFailoverHosts == null) {
|
||||
activeHost = null;
|
||||
this.failoverHosts = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.failoverHosts == null) {
|
||||
// initial setting
|
||||
getLog().out("setting initial failover hosts :");
|
||||
for (FailoverHost item : newFailoverHosts) {
|
||||
getLog().out(": " + item.getHostname());
|
||||
}
|
||||
} else {
|
||||
// whats new, whats removed...
|
||||
Map<String, FailoverHost> currentHosts = new HashMap<String, FailoverHost>();
|
||||
for (FailoverHost item : this.failoverHosts) {
|
||||
currentHosts.put(item.getHostname(), item);
|
||||
}
|
||||
|
||||
for (FailoverHost item : newFailoverHosts) {
|
||||
if (currentHosts.containsKey(item.getHostname())) {
|
||||
// enthalten, also aus dieser Liste lösche
|
||||
currentHosts.remove(item.getHostname());
|
||||
} else {
|
||||
// bisher nicht enthalten, also neu
|
||||
getLog().out("new failover host " + item.getHostname());
|
||||
newHosts = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentHosts.size() > 0) {
|
||||
getLog().out("some failover host removed ");
|
||||
for (FailoverHost removedHost : currentHosts.values()) {
|
||||
getLog().out(" - " + removedHost.getHostname());
|
||||
}
|
||||
} else {
|
||||
if (!newHosts) {
|
||||
getLog().out("failover host list remains unchanged ");
|
||||
for (FailoverHost item : newFailoverHosts) {
|
||||
getLog().out(":" + item.getHostname());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.failoverHosts = newFailoverHosts;
|
||||
|
||||
// der erste Host in der Liste ist auch der Host, zu dem die aufrufe ohne Failover gehen!!!
|
||||
if (activeHost == null) {
|
||||
if (newFailoverHosts.size() > 0) {
|
||||
activeHost = newFailoverHosts.get(0);
|
||||
} else {
|
||||
// clean default host
|
||||
activeHost = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a host from the failover list.
|
||||
*
|
||||
* If the host is the currently active host {@link #getActiveHost()} then the current host is set to null<br>
|
||||
* If the host is not in the host list then nothing happens
|
||||
*
|
||||
* @param host
|
||||
* the host to be removed; do nothing if host is null
|
||||
*/
|
||||
public void remove(FailoverHost host) {
|
||||
if (host == null) {
|
||||
return;
|
||||
}
|
||||
getLog().out("remove host " + host.getHostname() + " from failover list");
|
||||
for (int i = 0; i < getList().size(); i++) {
|
||||
FailoverHost item = getList().get(i);
|
||||
if (item.getHostname().equals(host.getHostname())) {
|
||||
getList().remove(i);
|
||||
getLog().out("host " + item.getHostname() + " removed from failover list");
|
||||
}
|
||||
}
|
||||
if (activeHost != null && activeHost.getHostname().equals(host.getHostname())) {
|
||||
setActiveHost(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of hosts in the failover list
|
||||
*/
|
||||
public int size() {
|
||||
return failoverHosts == null ? 0 : failoverHosts.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list of currently known host to fail over
|
||||
*/
|
||||
public List<FailoverHost> getList() {
|
||||
return failoverHosts == null ? new ArrayList<FailoverHost>() : failoverHosts;
|
||||
}
|
||||
|
||||
public FailoverHost getActiveHost() {
|
||||
return activeHost;
|
||||
}
|
||||
|
||||
public void setActiveHost(FailoverHost host) {
|
||||
if (host == null) {
|
||||
getLog().out("clear active failover hosts");
|
||||
} else {
|
||||
getLog().out("set " + host.getHostname() + " as active failover hosts");
|
||||
}
|
||||
this.activeHost = host;
|
||||
}
|
||||
|
||||
public FailoverHost getNextFailoverHost() {
|
||||
FailoverHost failoverHost = null;
|
||||
getLog().out("scanning for other failover hosts. list contains a total of " + size() + " hosts");
|
||||
for (FailoverHost host : getList()) {
|
||||
if (host.equals(getActiveHost())) {
|
||||
continue;
|
||||
}
|
||||
failoverHost = host;
|
||||
getLog().out("next failover hosts is " + host.getHostname());
|
||||
break;
|
||||
}
|
||||
|
||||
// den nächsten aus der Liste ohne den defaultHost
|
||||
if (size() == 0) {
|
||||
getLog().err("No more failover host available!");
|
||||
}
|
||||
return failoverHost;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 2016 iTAC Software AG, Germany. All Rights Reserved.
|
||||
*
|
||||
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
|
||||
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
|
||||
* without the written permission of iTAC Software AG.
|
||||
*/
|
||||
package com.itac.mes.cogiscan;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.ConnectException;
|
||||
import java.util.List;
|
||||
|
||||
import com.itac.mes.cogiscan.data.ErrorDetail;
|
||||
import com.itac.mes.cogiscan.data.MesFailoverResponse;
|
||||
import com.itac.mes.cogiscan.data.MesResponse;
|
||||
import com.itac.mes.cogiscan.sockets.IhapHandler;
|
||||
import com.itac.mes.datainterface.data.IMesServicesLog;
|
||||
|
||||
public class FailoverInvocationHandler extends FailoverHostList implements InvocationHandler, IFailoverProxy {
|
||||
|
||||
public FailoverInvocationHandler(IMesServicesLog log) {
|
||||
super(log);
|
||||
}
|
||||
|
||||
/**
|
||||
* gets a new communication channel with specified name
|
||||
*
|
||||
* @param channelName
|
||||
* the name for the channel
|
||||
* @param connectionListener
|
||||
* @return the communication channel where mesFunctions are exceuted (remote calls via IHap)
|
||||
* @throws IOException
|
||||
*/
|
||||
private synchronized IMesServicesChannel getConnection(String channelName, PropertyChangeListener connectionListener)
|
||||
throws IOException {
|
||||
if (getActiveHost() == null) {
|
||||
getLog().err("cannot get new connection " + channelName + " because active host is unset");
|
||||
return null;
|
||||
}
|
||||
String sHostname = getActiveHost().getHostname();
|
||||
int iPort = getActiveHost().getPort();
|
||||
getLog().out("get new connection " + channelName + " for " + sHostname + ":" + iPort);
|
||||
IMesServicesChannel serviceChannel = IhapHandler.connect(sHostname, iPort, channelName, null, this.getClass().getClassLoader(),
|
||||
getLog());
|
||||
// start the communication channel
|
||||
serviceChannel.startup();
|
||||
return serviceChannel;
|
||||
}
|
||||
|
||||
private void handleThrowable(Object response, Throwable throwable) {
|
||||
if (!(response instanceof MesResponse)) {
|
||||
return;
|
||||
}
|
||||
MesResponse mesResponse = (MesResponse) response;
|
||||
mesResponse.setTotalResult(IMesServices.MES_RESULT_NOT_OK);
|
||||
if (throwable instanceof CogiscanException) {
|
||||
setResponseValues(mesResponse, ((CogiscanException) throwable).getResponseDetail());
|
||||
} else if (throwable instanceof IOException) {
|
||||
mesResponse.getErrorDetails().add(getErrorDetail(throwable.getMessage(), ResponseDetail.COMMUNICATION_FAILURE.getCode()));
|
||||
} else {
|
||||
mesResponse.getErrorDetails().add(getErrorDetail(throwable.getMessage(), ResponseDetail.PROCESSED_WITH_EXCEPTION.getCode()));
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// convenient method
|
||||
private ErrorDetail getErrorDetail(String detail, int code) {
|
||||
ErrorDetail errorDetail = new ErrorDetail();
|
||||
errorDetail.setCode(code);
|
||||
errorDetail.setDetail(detail);
|
||||
return errorDetail;
|
||||
}
|
||||
|
||||
/**
|
||||
* finalizing means closing communication channel and loggin response Object
|
||||
*
|
||||
* @param connection
|
||||
* the used connection
|
||||
*/
|
||||
private void finalizeRequest(IMesServicesChannel connection) {
|
||||
if (connection != null) {
|
||||
connection.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized IMesServicesChannel getConnection(String string) throws IOException {
|
||||
return getConnection(string, null);
|
||||
}
|
||||
|
||||
private void setResponseValues(MesResponse response, ResponseDetail responseDetail) {
|
||||
if (responseDetail == ResponseDetail.OK) {
|
||||
response.setTotalResult(IMesServices.MES_RESULT_OK);
|
||||
return;
|
||||
}
|
||||
response.setTotalResult(IMesServices.MES_RESULT_NOT_OK);
|
||||
response.getErrorDetails().add(getErrorDetail(responseDetail.getText(), responseDetail.getCode()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
// special handling for a couple of function (mesStart, mesStop, getFailoverHosts..FailoverInvocationHandler.)
|
||||
Object response = method.getReturnType().newInstance();
|
||||
|
||||
// if no failoverhost available return error
|
||||
if (getActiveHost() == null && size() == 0) {
|
||||
// no host set, no failover available --> fail
|
||||
return null;
|
||||
}
|
||||
|
||||
// do a failover for all methods startswith "mes" (operational methods)
|
||||
if (method.getName().startsWith("mes")) {
|
||||
|
||||
IMesServicesChannel connection = null;
|
||||
|
||||
try {
|
||||
|
||||
boolean callFailed = false;
|
||||
do {
|
||||
try {
|
||||
callFailed = false;
|
||||
getLog().out("call " + method.getName() + "@" + getActiveHost().getHostname());
|
||||
connection = getConnection(method.getName());
|
||||
if (connection == null) {
|
||||
callFailed = true;
|
||||
} else {
|
||||
response = method.invoke(connection, args);
|
||||
if (response == null) {
|
||||
callFailed = true;
|
||||
} else {
|
||||
|
||||
if ((response instanceof MesResponse)) {
|
||||
MesResponse responseObject = (MesResponse) response;
|
||||
if (responseObject.getTotalResult() == MesServices.MES_RESULT_NOT_OK) {
|
||||
// set DetailResult to COMMUNICATION_FAILURE
|
||||
// repeat this call to another host
|
||||
callFailed = hasCommunicationFailure(responseObject.getErrorDetails());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ConnectException ce) {
|
||||
callFailed = true;
|
||||
}
|
||||
|
||||
if (callFailed) {
|
||||
if (connection != null) {
|
||||
connection.shutdown();
|
||||
// explicit finalize this connection
|
||||
connection = null;
|
||||
}
|
||||
remove(getActiveHost());
|
||||
setActiveHost(getNextFailoverHost());
|
||||
}
|
||||
} while (callFailed && getActiveHost() != null);
|
||||
|
||||
// if failover did not find any available host return communication error
|
||||
if (getActiveHost() == null) {
|
||||
|
||||
if ((response instanceof MesResponse)) {
|
||||
MesResponse responseObject = (MesResponse) response;
|
||||
responseObject.getErrorDetails()
|
||||
.add(getErrorDetail("no failover host active", ResponseDetail.COMMUNICATION_FAILURE.getCode()));
|
||||
responseObject.setTotalResult(IMesServices.MES_RESULT_NOT_OK);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Throwable throwable) {
|
||||
handleThrowable(response, throwable);
|
||||
} finally {
|
||||
|
||||
if (response instanceof MesFailoverResponse) {
|
||||
// internally update the list
|
||||
setFailover(((MesFailoverResponse) response).getFailoverHosts());
|
||||
}
|
||||
|
||||
finalizeRequest(connection);
|
||||
}
|
||||
} else {
|
||||
// simply call the method, no failover for them
|
||||
response = method.invoke(proxy, args);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
private boolean hasCommunicationFailure(List<ErrorDetail> errorDetails) throws ConnectException {
|
||||
if (errorDetails == null) {
|
||||
return false;
|
||||
}
|
||||
for (ErrorDetail errDetail : errorDetails) {
|
||||
if (errDetail.getCode() == ResponseDetail.COMMUNICATION_FAILURE.getCode()) {
|
||||
getLog().err("communication failure on this connection");
|
||||
throw new ConnectException();
|
||||
}
|
||||
if (errDetail.getCode() == -10005) {
|
||||
getLog().err("communication failure on this connection");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) 2016 iTAC Software AG, Germany. All Rights Reserved.
|
||||
*
|
||||
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
|
||||
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
|
||||
* without the written permission of iTAC Software AG.
|
||||
*/
|
||||
package com.itac.mes.cogiscan;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.itac.mes.cogiscan.data.FailoverHost;
|
||||
|
||||
public interface IFailoverProxy {
|
||||
|
||||
public void setFailover(List<FailoverHost> failoverHosts);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.itac.mes.cogiscan;
|
||||
|
||||
public interface IMesServicesChannel extends IMesServices {
|
||||
|
||||
public boolean isShutdown();
|
||||
|
||||
public void startup();
|
||||
|
||||
public void shutdown();
|
||||
|
||||
public String getChannelName();
|
||||
|
||||
public void setChannelName(String channelName);
|
||||
}
|
||||
@@ -0,0 +1,642 @@
|
||||
/*
|
||||
* Copyright (c) 2010 iTAC Software AG, Germany. All Rights Reserved.
|
||||
*
|
||||
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
|
||||
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
|
||||
* without the written permission of iTAC Software AG.
|
||||
*/
|
||||
package com.itac.mes.cogiscan;
|
||||
|
||||
import static com.itac.mes.cogiscan.ResponseDetail.OK;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.jws.WebService;
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBElement;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Marshaller;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import com.itac.mes.cogiscan.data.CheckContainerRequest;
|
||||
import com.itac.mes.cogiscan.data.CheckContainerResponse;
|
||||
import com.itac.mes.cogiscan.data.CreateContainerRequest;
|
||||
import com.itac.mes.cogiscan.data.CreateContainerResponse;
|
||||
import com.itac.mes.cogiscan.data.ErrorDetail;
|
||||
import com.itac.mes.cogiscan.data.FailoverHost;
|
||||
import com.itac.mes.cogiscan.data.InterlockingRequest;
|
||||
import com.itac.mes.cogiscan.data.InterlockingResponse;
|
||||
import com.itac.mes.cogiscan.data.ItemProducedRequest;
|
||||
import com.itac.mes.cogiscan.data.MachineMessageRequest;
|
||||
import com.itac.mes.cogiscan.data.MachineStatusRequest;
|
||||
import com.itac.mes.cogiscan.data.MaterialConsumedRequest;
|
||||
import com.itac.mes.cogiscan.data.MesConfigurationResponse;
|
||||
import com.itac.mes.cogiscan.data.MesFailoverResponse;
|
||||
import com.itac.mes.cogiscan.data.MesRequest;
|
||||
import com.itac.mes.cogiscan.data.MesResponse;
|
||||
import com.itac.mes.cogiscan.data.MesStartRequest;
|
||||
import com.itac.mes.cogiscan.data.PanelInfoRequest;
|
||||
import com.itac.mes.cogiscan.data.PanelInfoResponse;
|
||||
import com.itac.mes.cogiscan.data.PlacementRecipeCheckRequest;
|
||||
import com.itac.mes.cogiscan.data.PlacementRecipeCheckResponse;
|
||||
import com.itac.mes.cogiscan.sockets.IhapHandler;
|
||||
import com.itac.mes.datainterface.data.IMesServicesLog;
|
||||
|
||||
/**
|
||||
* @author frankp created 2011
|
||||
*/
|
||||
@WebService(endpointInterface = "com.itac.mes.cogiscan.IMesServices")
|
||||
public class MesServices implements IMesServices, IMesServicesLog {
|
||||
|
||||
private static String LOG_PREFIX = "iTAC.MES.Suite SMT-Plugin > ";
|
||||
|
||||
/** the port number must be in this allowed range */
|
||||
private static final int MIN_PORT = 1023;
|
||||
private static final int MAX_PORT = 49150;
|
||||
// 10 minutes default
|
||||
private static final long DEFAULT_REFRESH_INTERVAL = 600000;
|
||||
|
||||
// some bool flags for operation
|
||||
private boolean configured;
|
||||
private boolean active;
|
||||
|
||||
private boolean logDetails = true;
|
||||
|
||||
// Ciogiscan needs an own classloader due to unknown reasons
|
||||
private ClassLoader classloader;
|
||||
// every call to a mes host needs an own id; the id does not change when a call is completed on a failover host
|
||||
private RequestIdGenerator idGenerator = new RequestIdGenerator();
|
||||
// the invocation handler accepts all calls from the failoverProxy
|
||||
// additionally this is the way to set properties / values which are not part of the mes... Interface
|
||||
private FailoverInvocationHandler failoverInvocationHandler;
|
||||
// this proxy delegates the calls to all known failover hosts
|
||||
private IMesServices failoverProxy;
|
||||
// context and marshaller for logging
|
||||
private JAXBContext jaxbContext;
|
||||
private Marshaller marshaller;
|
||||
|
||||
// failover detection
|
||||
private static int updateThreadCount;
|
||||
private Thread failoverUpdateThread;
|
||||
|
||||
private long refreshFailoverhostsInterval;
|
||||
|
||||
/**
|
||||
* The default constructor
|
||||
*/
|
||||
private MesServices() {
|
||||
super();
|
||||
setConfigured(false);
|
||||
setActive(false);
|
||||
|
||||
if (System.getProperties().containsKey(MES_LOG_PREFIX)) {
|
||||
LOG_PREFIX = System.getProperty(MES_LOG_PREFIX);
|
||||
}
|
||||
if (System.getProperties().containsKey(MES_LOG_DETAILS)) {
|
||||
String sLogDetails = System.getProperty(MES_LOG_DETAILS);
|
||||
logDetails = sLogDetails.equalsIgnoreCase(Boolean.TRUE.toString()) || sLogDetails.equals("1");
|
||||
}
|
||||
|
||||
// create and initialize the failover proxy
|
||||
failoverInvocationHandler = new FailoverInvocationHandler(this);
|
||||
failoverProxy = (IMesServices) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class<?>[] { IMesServices.class },
|
||||
failoverInvocationHandler);
|
||||
}
|
||||
|
||||
public MesServices(String hostname, int port) {
|
||||
this();
|
||||
if (!isHostNameValid(hostname)) {
|
||||
err("hostname must not be null or empty");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isPortValid(port)) {
|
||||
err(MessageFormat.format("value {0} is out of range {1}..{2}", port, MIN_PORT, MAX_PORT));
|
||||
return;
|
||||
}
|
||||
|
||||
setConfigured(true);
|
||||
FailoverHost failoverHost = new FailoverHost();
|
||||
failoverHost.setHostname(hostname);
|
||||
failoverHost.setPort(port);
|
||||
|
||||
List<FailoverHost> failoverHosts = new ArrayList<FailoverHost>();
|
||||
failoverHosts.add(failoverHost);
|
||||
failoverInvocationHandler.setFailover(failoverHosts);
|
||||
}
|
||||
|
||||
protected void setRefreshFailoverhostsInterval(long refreshFailoverhostsInterval) {
|
||||
this.refreshFailoverhostsInterval = refreshFailoverhostsInterval;
|
||||
}
|
||||
|
||||
protected boolean isPortValid(int newPort) {
|
||||
boolean result = newPort >= MIN_PORT && newPort <= MAX_PORT;
|
||||
return result;
|
||||
}
|
||||
|
||||
protected boolean isHostNameValid(String hostname) {
|
||||
return hostname != null && !hostname.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Vorbedingungen sind dass der Request gesetzt ist, sowie die Konfiguration und die aktivierung des Plugin
|
||||
*
|
||||
* @param mesResponse
|
||||
* @param mesRequest
|
||||
* @throws CogiscanException
|
||||
*/
|
||||
protected void checkPreconditions(MesResponse mesResponse, MesRequest mesRequest) throws CogiscanException {
|
||||
if (mesRequest == null) {
|
||||
throw new CogiscanException(ResponseDetail.REQUEST_IS_NULL);
|
||||
}
|
||||
if (mesResponse == null) {
|
||||
throw new CogiscanException(ResponseDetail.RESPONSE_IS_NULL);
|
||||
}
|
||||
if (mesRequest.getRequestId() <= 0) {
|
||||
mesRequest.setRequestId(idGenerator.getNextId());
|
||||
}
|
||||
if (mesRequest.getEventDate() == null) {
|
||||
mesRequest.setEventDate(new Date());
|
||||
}
|
||||
// Request ausgeben
|
||||
logRequest(mesRequest);
|
||||
// requestId aus Request in den Response uebernehmen
|
||||
mesResponse.setRequestId(mesRequest.getRequestId());
|
||||
// Konfigurationsprobleme checken
|
||||
if (!isConfigured()) {
|
||||
throw new CogiscanException(ResponseDetail.PLUGIN_NOT_CONFIGURED);
|
||||
}
|
||||
if (!isActive()) {
|
||||
throw new CogiscanException(ResponseDetail.PLUGIN_NOT_ACTIVE);
|
||||
}
|
||||
setResponseValues(mesResponse, OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* finalizing means closing communication channel and loggin response Object
|
||||
*
|
||||
* @param responseObject
|
||||
* the responseObject
|
||||
*/
|
||||
private void finalizeRequest(MesResponse responseObject) {
|
||||
logResponse(responseObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cogiscan has an own classloader; therefore it is necessary for them to set this classloader<br>
|
||||
*
|
||||
* @param classloader
|
||||
* a default classloader if no classloader was set with {@linkplain IhapHandler#setClassLoader}
|
||||
*/
|
||||
private ClassLoader getClassLoader() {
|
||||
if (classloader == null) {
|
||||
classloader = MesServices.class.getClassLoader();
|
||||
}
|
||||
return classloader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cogiscan has an own classloader; therefore it is necessary for them to set this classloader<br>
|
||||
* it is not necessary in itac applications such as simulation
|
||||
*
|
||||
* @param classloader
|
||||
*/
|
||||
public void setClassLoader(ClassLoader classloader) {
|
||||
this.classloader = classloader;
|
||||
}
|
||||
|
||||
// convenient method
|
||||
private ErrorDetail getErrorDetail(String detail, int code) {
|
||||
ErrorDetail errorDetail = new ErrorDetail();
|
||||
errorDetail.setCode(code);
|
||||
errorDetail.setDetail(detail);
|
||||
return errorDetail;
|
||||
}
|
||||
|
||||
protected void handleThrowable(MesResponse response, Throwable throwable) {
|
||||
response.setTotalResult(IMesServices.MES_RESULT_NOT_OK);
|
||||
if (throwable instanceof CogiscanException) {
|
||||
setResponseValues(response, ((CogiscanException) throwable).getResponseDetail());
|
||||
} else if (throwable instanceof IOException) {
|
||||
response.getErrorDetails().add(getErrorDetail(throwable.getMessage(), ResponseDetail.COMMUNICATION_FAILURE.getCode()));
|
||||
} else {
|
||||
response.getErrorDetails().add(getErrorDetail(throwable.getMessage(), ResponseDetail.PROCESSED_WITH_EXCEPTION.getCode()));
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private void logResponse(MesResponse mesResponse) {
|
||||
if (mesResponse == null) {
|
||||
out("finish request, response is null");
|
||||
return;
|
||||
}
|
||||
if (!logDetails) {
|
||||
out("finish request " + mesResponse.getRequestId() + " with code " + mesResponse.getTotalResult());
|
||||
} else {
|
||||
try {
|
||||
JAXBElement<?> jexbelement = new JAXBElement(new QName(mesResponse.getClass().getSimpleName()), mesResponse.getClass(),
|
||||
mesResponse);
|
||||
StringWriter stw = new StringWriter();
|
||||
getMarshaller().marshal(jexbelement, stw);
|
||||
out(stw.toString());
|
||||
} catch (JAXBException e) {
|
||||
err("no jaxb context or marshaller created");
|
||||
} catch (Throwable e) {
|
||||
err("Error logging mesResponse details");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Marshaller getMarshaller() throws JAXBException {
|
||||
if (marshaller == null) {
|
||||
marshaller = getJaxbContext().createMarshaller();
|
||||
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
|
||||
}
|
||||
return marshaller;
|
||||
}
|
||||
|
||||
private JAXBContext getJaxbContext() throws JAXBException {
|
||||
// all classes from the data package
|
||||
if (jaxbContext == null) {
|
||||
Class<?>[] classes = new Class[] { CreateContainerRequest.class, CreateContainerResponse.class, CheckContainerRequest.class,
|
||||
MesFailoverResponse.class, CheckContainerResponse.class, InterlockingRequest.class, InterlockingResponse.class,
|
||||
ItemProducedRequest.class, MachineMessageRequest.class, MachineStatusRequest.class, MaterialConsumedRequest.class,
|
||||
MesConfigurationResponse.class, MesRequest.class, MesResponse.class, PlacementRecipeCheckRequest.class,
|
||||
PlacementRecipeCheckResponse.class };
|
||||
jaxbContext = JAXBContext.newInstance(classes);
|
||||
}
|
||||
return jaxbContext;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private void logRequest(MesRequest mesRequest) {
|
||||
if (mesRequest == null) {
|
||||
out("request is null");
|
||||
return;
|
||||
}
|
||||
if (!logDetails) {
|
||||
out("start request " + mesRequest.getRequestId() + " (" + mesRequest.getClass().getSimpleName() + ")");
|
||||
} else {
|
||||
try {
|
||||
JAXBElement<?> jexbelement = new JAXBElement(new QName(mesRequest.getClass().getSimpleName()), mesRequest.getClass(),
|
||||
mesRequest);
|
||||
StringWriter stw = new StringWriter();
|
||||
getMarshaller().marshal(jexbelement, stw);
|
||||
out(stw.toString());
|
||||
} catch (JAXBException e) {
|
||||
err("no jaxb context or marshaller created");
|
||||
} catch (Throwable e) {
|
||||
err("Error logging mesRequest details");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void setResponseValues(MesResponse response, ResponseDetail responseDetail) {
|
||||
if (responseDetail == ResponseDetail.OK) {
|
||||
response.setTotalResult(IMesServices.MES_RESULT_OK);
|
||||
return;
|
||||
}
|
||||
response.setTotalResult(IMesServices.MES_RESULT_NOT_OK);
|
||||
response.getErrorDetails().add(getErrorDetail(responseDetail.getText(), responseDetail.getCode()));
|
||||
}
|
||||
|
||||
protected IMesServices getFailoverProxy() {
|
||||
return failoverProxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreateContainerResponse mesCreateContainer(CreateContainerRequest createContainerRequest) {
|
||||
CreateContainerResponse responseObject = new CreateContainerResponse();
|
||||
try {
|
||||
checkPreconditions(responseObject, createContainerRequest);
|
||||
responseObject = getFailoverProxy().mesCreateContainer(createContainerRequest);
|
||||
} catch (Throwable throwable) {
|
||||
handleThrowable(responseObject, throwable);
|
||||
} finally {
|
||||
finalizeRequest(responseObject);
|
||||
}
|
||||
return responseObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CheckContainerResponse mesCheckContainer(CheckContainerRequest checkContainerRequest) {
|
||||
CheckContainerResponse responseObject = new CheckContainerResponse();
|
||||
try {
|
||||
checkPreconditions(responseObject, checkContainerRequest);
|
||||
responseObject = getFailoverProxy().mesCheckContainer(checkContainerRequest);
|
||||
} catch (Throwable throwable) {
|
||||
handleThrowable(responseObject, throwable);
|
||||
} finally {
|
||||
finalizeRequest(responseObject);
|
||||
}
|
||||
return responseObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlacementRecipeCheckResponse mesCheckPlacementRecipe(PlacementRecipeCheckRequest placementRecipeCheckRequest) {
|
||||
PlacementRecipeCheckResponse responseObject = new PlacementRecipeCheckResponse();
|
||||
try {
|
||||
checkPreconditions(responseObject, placementRecipeCheckRequest);
|
||||
responseObject = getFailoverProxy().mesCheckPlacementRecipe(placementRecipeCheckRequest);
|
||||
} catch (Throwable throwable) {
|
||||
handleThrowable(responseObject, throwable);
|
||||
} finally {
|
||||
finalizeRequest(responseObject);
|
||||
}
|
||||
return responseObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InterlockingResponse mesInterlocking(InterlockingRequest interlockingRequest) {
|
||||
InterlockingResponse responseObject = new InterlockingResponse();
|
||||
try {
|
||||
checkPreconditions(responseObject, interlockingRequest);
|
||||
responseObject = getFailoverProxy().mesInterlocking(interlockingRequest);
|
||||
} catch (Throwable throwable) {
|
||||
handleThrowable(responseObject, throwable);
|
||||
} finally {
|
||||
finalizeRequest(responseObject);
|
||||
}
|
||||
return responseObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PanelInfoResponse mesPanelInformation(PanelInfoRequest infoRequest) {
|
||||
PanelInfoResponse responseObject = new PanelInfoResponse();
|
||||
try {
|
||||
checkPreconditions(responseObject, infoRequest);
|
||||
responseObject = getFailoverProxy().mesPanelInformation(infoRequest);
|
||||
} catch (Throwable throwable) {
|
||||
handleThrowable(responseObject, throwable);
|
||||
} finally {
|
||||
finalizeRequest(responseObject);
|
||||
}
|
||||
return responseObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MesResponse mesItemProduced(ItemProducedRequest itemProducedRequest) {
|
||||
MesResponse responseObject = new MesResponse();
|
||||
try {
|
||||
checkPreconditions(responseObject, itemProducedRequest);
|
||||
responseObject = getFailoverProxy().mesItemProduced(itemProducedRequest);
|
||||
} catch (Throwable throwable) {
|
||||
handleThrowable(responseObject, throwable);
|
||||
} finally {
|
||||
finalizeRequest(responseObject);
|
||||
}
|
||||
return responseObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MesResponse mesMachineState(MachineStatusRequest machineStatus) {
|
||||
MesResponse responseObject = new MesResponse();
|
||||
try {
|
||||
checkPreconditions(responseObject, machineStatus);
|
||||
responseObject = getFailoverProxy().mesMachineState(machineStatus);
|
||||
} catch (Throwable throwable) {
|
||||
handleThrowable(responseObject, throwable);
|
||||
} finally {
|
||||
finalizeRequest(responseObject);
|
||||
}
|
||||
return responseObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MesResponse mesMachineMessage(MachineMessageRequest machineMessage) {
|
||||
MesResponse responseObject = new MesResponse();
|
||||
try {
|
||||
checkPreconditions(responseObject, machineMessage);
|
||||
responseObject = getFailoverProxy().mesMachineMessage(machineMessage);
|
||||
} catch (Throwable throwable) {
|
||||
handleThrowable(responseObject, throwable);
|
||||
} finally {
|
||||
finalizeRequest(responseObject);
|
||||
}
|
||||
return responseObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MesResponse mesMaterialConsumed(MaterialConsumedRequest materialConsumedRequest) {
|
||||
MesResponse responseObject = new MesResponse();
|
||||
try {
|
||||
checkPreconditions(responseObject, materialConsumedRequest);
|
||||
responseObject = getFailoverProxy().mesMaterialConsumed(materialConsumedRequest);
|
||||
} catch (Throwable throwable) {
|
||||
handleThrowable(responseObject, throwable);
|
||||
} finally {
|
||||
finalizeRequest(responseObject);
|
||||
}
|
||||
return responseObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MesConfigurationResponse mesGetConfiguration(MesRequest mesRequest) {
|
||||
MesConfigurationResponse responseObject = new MesConfigurationResponse();
|
||||
try {
|
||||
checkPreconditions(responseObject, mesRequest);
|
||||
responseObject = getFailoverProxy().mesGetConfiguration(mesRequest);
|
||||
} catch (Throwable throwable) {
|
||||
handleThrowable(responseObject, throwable);
|
||||
} finally {
|
||||
logResponse(responseObject);
|
||||
}
|
||||
return responseObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* convienience method, for compatibility with older version
|
||||
*/
|
||||
public MesResponse mesStart(MesRequest mesRequest) {
|
||||
MesStartRequest mesStart = new MesStartRequest();
|
||||
mesStart.setRequestId(mesRequest.getRequestId());
|
||||
mesStart.setEventDate(mesRequest.getEventDate());
|
||||
mesStart.getStartDetails().add("version=1.0");
|
||||
return mesStart(mesStart);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MesResponse mesStart(MesStartRequest mesRequest) {
|
||||
MesResponse responseObject = new MesResponse();
|
||||
try {
|
||||
// check properties for logging and create marshaller for logging
|
||||
if (System.getProperties().containsKey(MES_LOG_PREFIX)) {
|
||||
LOG_PREFIX = System.getProperty(MES_LOG_PREFIX);
|
||||
}
|
||||
if (System.getProperties().containsKey(MES_LOG_DETAILS)) {
|
||||
String sLogDetails = System.getProperty(MES_LOG_DETAILS);
|
||||
logDetails = sLogDetails.equalsIgnoreCase(Boolean.TRUE.toString()) || sLogDetails.equals("1");
|
||||
}
|
||||
|
||||
// check mes functionality
|
||||
if (mesRequest == null) {
|
||||
throw new CogiscanException(ResponseDetail.REQUEST_IS_NULL);
|
||||
}
|
||||
|
||||
if (!isConfigured()) {
|
||||
throw new CogiscanException(ResponseDetail.MES_NOT_CONFIGURED_PROPERLY);
|
||||
}
|
||||
|
||||
if (isActive()) {
|
||||
// do not ado activation twice
|
||||
setResponseValues(responseObject, ResponseDetail.OK);
|
||||
return responseObject;
|
||||
}
|
||||
|
||||
long start = System.nanoTime();
|
||||
responseObject = getFailoverProxy().mesStart(mesRequest);
|
||||
long finished = System.nanoTime();
|
||||
out("roundtrip = " + ((finished - start) / 1000L) + " microseconds");
|
||||
if (responseObject.getTotalResult() == MES_RESULT_OK) {
|
||||
setActive(true);
|
||||
startUpdateThread();
|
||||
}
|
||||
} catch (CogiscanException cse) {
|
||||
handleThrowable(responseObject, cse);
|
||||
} finally {
|
||||
logResponse(responseObject);
|
||||
}
|
||||
return responseObject;
|
||||
}
|
||||
|
||||
protected void setActive(boolean active) {
|
||||
if (!this.active && active) {
|
||||
out("setting MesServices active");
|
||||
} else if (this.active && !active) {
|
||||
out("setting MesServices inactive");
|
||||
}
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
protected boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
protected boolean isConfigured() {
|
||||
return configured;
|
||||
}
|
||||
|
||||
protected void setConfigured(boolean configured) {
|
||||
if (!this.configured && configured) {
|
||||
out("setting MesServices configured");
|
||||
} else if (this.configured && !configured) {
|
||||
out("setting MesServices configured");
|
||||
}
|
||||
this.configured = configured;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MesResponse mesGetStatus(MesRequest mesRequest) {
|
||||
MesResponse responseObject = new MesResponse();
|
||||
try {
|
||||
checkPreconditions(responseObject, mesRequest);
|
||||
responseObject = getFailoverProxy().mesGetStatus(mesRequest);
|
||||
} catch (Throwable throwable) {
|
||||
handleThrowable(responseObject, throwable);
|
||||
} finally {
|
||||
finalizeRequest(responseObject);
|
||||
}
|
||||
return responseObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MesResponse mesStop(MesRequest mesRequest) {
|
||||
MesResponse responseObject = new MesResponse();
|
||||
try {
|
||||
checkPreconditions(responseObject, mesRequest);
|
||||
responseObject = getFailoverProxy().mesStop(mesRequest);
|
||||
} catch (Throwable throwable) {
|
||||
handleThrowable(responseObject, throwable);
|
||||
} finally {
|
||||
finalizeRequest(responseObject);
|
||||
}
|
||||
setActive(false);
|
||||
stopUpdateThread();
|
||||
|
||||
return responseObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MesFailoverResponse mesGetFailoverList(MesRequest failoverRequest) {
|
||||
MesFailoverResponse responseObject = new MesFailoverResponse();
|
||||
try {
|
||||
checkPreconditions(responseObject, failoverRequest);
|
||||
responseObject = getFailoverProxy().mesGetFailoverList(failoverRequest);
|
||||
} catch (Throwable throwable) {
|
||||
handleThrowable(responseObject, throwable);
|
||||
} finally {
|
||||
finalizeRequest(responseObject);
|
||||
}
|
||||
return responseObject;
|
||||
}
|
||||
|
||||
protected synchronized Thread getUpdateThread() {
|
||||
String threadName = "failoverUpdateThread#" + (updateThreadCount++);
|
||||
Thread failoverUpdateThread = new Thread(threadName) {
|
||||
private int runCounter;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
out(getName() + "renew failoverHost list thread started, call #" + (++runCounter));
|
||||
while (true) {
|
||||
try {
|
||||
if (refreshFailoverhostsInterval < DEFAULT_REFRESH_INTERVAL) {
|
||||
Thread.sleep(DEFAULT_REFRESH_INTERVAL);
|
||||
} else {
|
||||
Thread.sleep(refreshFailoverhostsInterval);
|
||||
}
|
||||
mesGetFailoverList(new MesRequest());
|
||||
out(getName() + "renew failoverHost list finished");
|
||||
} catch (InterruptedException e) {
|
||||
err(getName() + "interrupted or failed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
out(getName() + "closed");
|
||||
}
|
||||
};
|
||||
out(threadName + "created");
|
||||
return failoverUpdateThread;
|
||||
}
|
||||
|
||||
protected void startUpdateThread() {
|
||||
// if connection is established and OK start observation thread
|
||||
if (failoverUpdateThread == null || !failoverUpdateThread.isAlive()) {
|
||||
failoverUpdateThread = getUpdateThread();
|
||||
failoverUpdateThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* the current active channel was closed (port closed on DataInterface)
|
||||
*
|
||||
* @param channelName
|
||||
*/
|
||||
protected void stopUpdateThread() {
|
||||
out(" was closed by iTAC.MES.Suite DataInterface");
|
||||
// den Ueberwachungsthread stoppen
|
||||
if (failoverUpdateThread != null && failoverUpdateThread.isAlive()) {
|
||||
out(" stop " + failoverUpdateThread.getName() + " now");
|
||||
failoverUpdateThread.interrupt();
|
||||
failoverUpdateThread = null;
|
||||
} else {
|
||||
out(" already stopped");
|
||||
}
|
||||
}
|
||||
|
||||
public void out(String text) {
|
||||
System.out.println(LOG_PREFIX + "[MesServices][" + Thread.currentThread().getName() + "] " + text);
|
||||
}
|
||||
|
||||
public void err(String text) {
|
||||
System.err.println(LOG_PREFIX + "[MesServices][" + Thread.currentThread().getName() + "] " + text);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2016 iTAC Software AG, Germany. All Rights Reserved.
|
||||
*
|
||||
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
|
||||
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
|
||||
* without the written permission of iTAC Software AG.
|
||||
*/
|
||||
package com.itac.mes.cogiscan;
|
||||
|
||||
public class RequestIdGenerator {
|
||||
|
||||
protected static int MIN_REQUEST_ID = 0;
|
||||
protected static int MAX_REQUEST_ID = 1000000;
|
||||
|
||||
private int requestId;
|
||||
|
||||
// creates an almost unique id
|
||||
public synchronized int getNextId() {
|
||||
requestId += 1;
|
||||
if (requestId >= MAX_REQUEST_ID) {
|
||||
requestId = MIN_REQUEST_ID;
|
||||
}
|
||||
return requestId;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2016 iTAC Software AG, Germany. All Rights Reserved.
|
||||
*
|
||||
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
|
||||
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
|
||||
* without the written permission of iTAC Software AG.
|
||||
*/
|
||||
package com.itac.mes.cogiscan;
|
||||
|
||||
public enum ResponseDetail {
|
||||
|
||||
// WARNINGS, HINTS: positive values
|
||||
//
|
||||
OK("", 0),
|
||||
// Plugin-ERRORS: negative values
|
||||
REQUEST_IS_NULL("request is null", -10001), //
|
||||
/** any call to MES before mesConfigure was called properly */
|
||||
PLUGIN_NOT_CONFIGURED("plugin not configured", -10002), //
|
||||
PLUGIN_NOT_ACTIVE("plugin not active", -10003), //
|
||||
PLUGIN_NOT_CONNECTED("plugin not connected " + ResponseDetail.MES_DATA_INTERFACE, -10004), //
|
||||
COMMUNICATION_FAILURE("communication failure", -10005), //
|
||||
WRONG_COMMUNICATION_PROPERTIES("communication properties wrong", -10006), //
|
||||
PLUGIN_VERSION_MISMATCH("plugin version mismatch", -10007), //
|
||||
RESPONSE_IS_NULL("response is null", -10008),
|
||||
// Errors from Data Interface negative values
|
||||
MES_NOT_CONNECTED(ResponseDetail.MES_DATA_INTERFACE + "is not connected", -20000), //
|
||||
MES_NOT_CONFIGURED_PROPERLY(ResponseDetail.MES_DATA_INTERFACE + "is not properly configured", -20001), //
|
||||
MES_NOT_INITIALIZED(ResponseDetail.MES_DATA_INTERFACE + "is not initialized", -20002), //
|
||||
PARSED_WITH_EXCEPTION(ResponseDetail.MES_DATA_INTERFACE + "caught an exception on parsing request", -20003), //
|
||||
PROCESSED_WITH_EXCEPTION(ResponseDetail.MES_DATA_INTERFACE + "caught an exception on processing request", -20004), //
|
||||
SERIALNUMBER_NOT_ALLOWED(ResponseDetail.MES_DATA_INTERFACE + "Serialnumber not allowed", -20005), //
|
||||
PARSE_PROBLEM(ResponseDetail.MES_DATA_INTERFACE + "has a problem parsing the request", -20006), //
|
||||
NOT_SENT(ResponseDetail.MES_DATA_INTERFACE + "did not sent data", -20007), //
|
||||
MES_SERVICE_NOT_REACHABLE("iTAC.MES.Suite service is not reachable", -20008), //
|
||||
;
|
||||
|
||||
private static final String MES_DATA_INTERFACE = "iTAC.MES.Suite DataInterface ";
|
||||
|
||||
private int code;
|
||||
private String text;
|
||||
|
||||
private ResponseDetail(String text, int code) {
|
||||
this.text = text;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2008 iTAC Software AG, Germany. All Rights Reserved.
|
||||
*
|
||||
* This software is protected by copyright. Under no circumstances may any part of this file in any form be copied,
|
||||
* printed, edited or otherwise distributed, be stored in a retrieval system, or be translated into another language
|
||||
* without the written permission of iTAC Software AG.
|
||||
*/
|
||||
package com.itac.mes.cogiscan.sockets;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import com.itac.mes.cogiscan.IMesServicesChannel;
|
||||
import com.itac.mes.datainterface.data.IMesServicesLog;
|
||||
import com.itac.mes.datainterface.socket.BaseIhapHandler;
|
||||
|
||||
/**
|
||||
* This handler delegates IMesService calls to a socket server for CommonSmt Interface
|
||||
*
|
||||
* @author frankp
|
||||
*
|
||||
*/
|
||||
public class IhapHandler extends BaseIhapHandler {
|
||||
|
||||
/**
|
||||
* This handler is responsible for calling all IMesServices functions at a socket server for this type.<br>
|
||||
*
|
||||
* @param host
|
||||
* the host where the server listens
|
||||
* @param port
|
||||
* the port the server listens
|
||||
* @param channelName
|
||||
* the name of the channel. As every channel has a unique name it is possible to debug server/client side
|
||||
* @param connectionStateCloseListener
|
||||
* detect wether a
|
||||
* @param classLoader
|
||||
* a classloader to override default class loader
|
||||
* @param log
|
||||
* the mesLog. if null prints direct to System.out/System.err
|
||||
* @return the reference to a base Handler
|
||||
* @throws IOException
|
||||
* thrown if no connection was established (server not available)
|
||||
*/
|
||||
public static IMesServicesChannel connect(String host, int port, String channelName,
|
||||
PropertyChangeListener connectionStateCloseListener, ClassLoader classLoader, IMesServicesLog log) throws IOException {
|
||||
// create a default connection, not bound to any type
|
||||
BaseIhapHandler handler = createHandler(host, port, channelName, connectionStateCloseListener, classLoader, log);
|
||||
|
||||
// create a proxy for a specific type (Interface)
|
||||
IMesServicesChannel mesServiceChannel = (IMesServicesChannel) Proxy.newProxyInstance(classLoader,
|
||||
new Class[] { IMesServicesChannel.class }, handler);
|
||||
|
||||
// set the channel name and transport it top server
|
||||
mesServiceChannel.setChannelName(channelName);
|
||||
return mesServiceChannel;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user