Hi all,
i have read all docs i could find about this topic but have not found a solution until now.
Got it to work with automated start/stop script including vnc but struggle with all the needed as2 ports and where to change them.
Is anybody out there using multiple installations with this release on the same linux machine, (eg: as2 test and production).
Additional: how to get the source code from sourceforge.net ? (could not find it).
Thanks for your help and regards ....
antsan,
its not possible at the moment to start more than an instance on a single machine. But waht would be the idea behind this?
The code could be found in the sourceforge cvs.
Regards
Heller
antsan,
sorry I did not get the point with the productive and test system. I agree that this is very important. But you have to use two different systems at the moment for this attempt.
Regards
Heller
thanks for your clear answer, when will it be possible ?
As far i have tracked down the problem it is only a port issue, but maybe because i'm not getting to the end of the startup i dont see all problems related to it.
Have seen that it is not possible to split data from binary, then as2 does not find one of the local servers, but when i install everything, (including binaries), into two different directories it seams to work, except the port issues.
for example the first one:
INFO: Starting mendelson opensource AS2 1.1 build 31 client-server interface, listening on port 1235
java.net.BindException: Address already in use
>>Why two as2 servers on the same machine:
We usualy offer permanently two connections to our partners, the production and test environment, (test for problems and during new implementations or changes).
If i have to install it on two servers it would result into 3-4 dmz servers for redundancy and failover reasons but we have only two currently.
Would be nice to install prod and test on the same machine, so we could install it on both dmz machines to get a redundant system.
Or is there another way to implement test and prod we could overcome the double installation ? (I'm new to as2 for this kind of questions).
I only need an identifier to differentiate between production and test what is available to external scripts to send and inject into our internal edi engines.
Regards and thanks for your help,
antsan
Just beep't into your source code and found the nice file:
comm/as2/preferences/PreferencesAS2.java
... where all the default parameters are located.
Why not loading these defaults from a file instead defining them static ?
This belongs to the wish list ;-)
cheers
why not run instances inside virtual machines on the same computer?
Hi all,
have found a possible solution for my TEST/PROD problem.
Because I dont want to add two additional machines, (virtual or physical, but still thanks for your input prost), i was looking for another solution and guess have found it.
It is possible to add more then one local station including different certificates, (nice feature, even sending from both works perfect).
So i defined two local AS2 ID's like: AS2Company and AS2CompanyTEST both of them use there own certificates to protect against typos, (sending a test message to prod and vise versa).
Speaks anything against it ?
antsan,
Thats ok from a technical perspective but I thought that you require two different installations because it might be required to perform updates, modifications and configuration changes on the test system before performing them on the productive system.
Regards
Heller
thanks for your response heller,
no, PROD/TEST is only what is says and message related, NOT AS2 related.
I need the TEST connection for new customers, problems and changes of message formats etc.
When a new customer is implemented in TEST we copy relevant data to PROD but keep the TEST as well. Like that we have the option to simulate problem messages or implement new ones or changes.
For a changes of AS2 i can use mine or another internal machine to test and figure out problems as i did with our two DMZ-AS2 machines.
TEST/PROD and failover is important for us. It does'nt matter how it is implemented, but implementing two new machines for a TEST environment would be a pain when there are other ways. ;-)
Sorry when i was not clear about it.
sorry for the (VERY) delayed response, my deployment has been working so no need to come here :D
I have 8 servers running on on machine (as only 1 local station allowed by default and needed multiple)
//$Header: /home/cvsroot/mec-as2/src/de/mendelson/comm/as2/preferences/PreferencesAS2.java,v 1.2 2008/07/09 08:45:05 amir Exp $
package de.mendelson.comm.as2.preferences;
import de.mendelson.comm.as2.AS2ServerVersion;
import de.mendelson.util.MecResourceBundle;
// JAXP
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
// SAX
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.util.prefs.*;
import java.util.*;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.awt.*;
import java.io.File;
import java.io.InputStream;
/*
* Copyright (C) mendelson-e-commerce GmbH Berlin Germany
*
* This software is subject to the license agreement set forth in the license.
* Please read and agree to all terms before using this software.
* Other product and brand names are trademarks of their respective owners.
*/
/**
* Class to manage the preferences of the AS2 server
*
* @author S.Heller
* @version $Revision: 1.2 $
*/
public class PreferencesAS2 {
/**
* Magic String(s).
*/
public static final String
KEYSTORE_PASS = "keystorepass",
PROXY_HOST = "proxyhost",
PROXY_PORT = "proxyport",
STR_LOCALHOST = "localhost",
AUTH_PROXY_USER = "proxyuser",
AUTH_PROXY_PASS = "proxypass",
AUTH_PROXY_USE = "proxyuseauth",
PROXY_USE = "proxyuse",
ERR_RESOURCE_BUNDLE_NOT_FOUND = "resource bundle not found",
AUTO_MSG_DELETE = "automsgdelete",
AUTO_MSG_DELETE_OLDERTHAN = "automsgdeleteolderthan",
STR_SPACE = " ",
AUTO_MSG_DELETE_LOG = "automsgdeletelog",
JNDI_PORT = "jndiport",
MQ_PROXY_PORT = "mqproxyport",
RECEIPT_PARTNER_SUBDIR = "receiptpartnersubdir",
HTTP_SEND_TIMEOUT = "httpsendtimeout",
STR_USRDIR = "user.dir",
STR_OSNAME = "os.name",
STR_MESSAGES = "messages",
STR_MECAS2 = "MEC_AS2",
STR_ONEZERONINENINE = "1099",
STR_QUAD_THREE = "3333",
STR_KEYSTORE_PATH = "jetty/etc/keystore",
ERR_UNABLE_TO_LOAD_XML = "Unable to load preferences XML file";
class PreferenceHandler extends DefaultHandler {
StringBuffer textBuffer;
public void startDocument() throws SAXException {
LOGGER.log(Level.INFO, "configuration file loaded, starting parse");
}
public void endDocument() throws SAXException {
LOGGER.log(Level.INFO, "finished parsing configuration file");
}
public void endElement(String namespaceURI,
String sName,
String qName) throws SAXException {
MEC_SETTINGS.put(qName, textBuffer.toString());
}
public void startElement(String namespaceURI,
String sName,
String qName,
Attributes attrs) throws SAXException {
textBuffer = new StringBuffer();
}
public void characters(char[] buf, int offset, int len)
throws SAXException {
String s = new String(buf, offset, len);
if (null == textBuffer) {
textBuffer = new StringBuffer(s);
} else {
textBuffer.append(s);
}
}
}
// set out version here
public static final long serialVersionUID = 1L;
/**
* Logger.
*/
private static final Logger LOGGER
= Logger.getLogger("de.mendelson.as2.preferences.PreferencesAS2");
static MecResourceBundle rb;
static {
//load resource bundle
try {
rb = (MecResourceBundle) ResourceBundle.getBundle(
ResourceBundlePreferences.class.getName());
} catch (MissingResourceException e) {
throw new RuntimeException(ERR_RESOURCE_BUNDLE_NOT_FOUND
+ e.getClassName());
}
}
private final int OS_WIN = 1;
private final int OS_OTHER = 2;
/**
* Error exit code.
*/
private final int INT_ERROR = -1;
/**
* Magic string(s).
*/
private final String STR_EIGHT_HUNDRED = "800";
/**
* Magic string(s).
*/
private final String STR_SIX_HUNDRED = "600";
/**
* Magic string(s).
*/
private final String STR_DE = "de";
/**
* Magic string(s).
*/
private final String STR_EN = "en";
/**
* Magic string(s).
*/
public static final String STR_WIN = "win";
/**
* Position of the client frame X
*/
public static final String FRAME_X = "frameguix";
/**
* Position of the client frame Y
*/
public static final String FRAME_Y = "frameguiy";
/**
* Position of the client frame height
*/
public static final String FRAME_HEIGHT = "frameguiheight";
/**
* Position of the IDE frame WIDTH
*/
public static final String FRAME_WIDTH = "frameguiwidth";
/**
* Language to use for the software localization
*/
public static final String LANGUAGE = "language";
/**
* the actual used server to connect to
*/
public static final String SERVER_HOST = "serverhost";
/**
* The RMI connection port
*/
public static final String SERVER_RMI_PORT = "serverrmiport";
/**
* RMI service
*/
public static final String SERVER_RMI_SERVICE = "rmiservice";
/**
* DB server
*/
public static final String SERVER_DB_PORT = "dbport";
/**
* client server comm port
*/
public static final String CLIENTSERVER_COMM_PORT = "clientservercommport";
/**
* Directory the messageparts are stored in
*/
public static final String DIR_MSG = "dirmsg";
public static final String ASYNC_MDN_TIMEOUT = "asyncmdntimeout";
/**
* keystore for user defined certs in https
*/
public static final String KEYSTORE_HTTPS_SEND = "httpsendkeystore";
/**
* password for user defined certs keystore in https
*/
public static final String
KEYSTORE_HTTPS_SEND_PASS = "httpsendkeystorepass";
/**
* The configuration file.
*/
public static final String DEFAULT_CONFIG = "mecpreferences.xml";
/**
* Settings stored for the user
*/
private Preferences preferences = null;
/**
* name of the operation system
*/
private String os = System.getProperty(STR_OSNAME);
/**
* this is where we save the settings
*/
private static final Map MEC_SETTINGS = new HashMap();
/**
* Initialize the preferences
*/
public PreferencesAS2() {
//on windows systems it is common to use as root.
//On Linux/Unix systems it is ok
//for only one user (lets say user account "mendelson" )
if (OS_WIN == getOS()) {
this.preferences =
Preferences.systemNodeForPackage(AS2ServerVersion.class);
} else {
this.preferences =
Preferences.userNodeForPackage(AS2ServerVersion.class);
}
// load in config on start-up.
if (MEC_SETTINGS.isEmpty())
loadConfig();
}
/**
* loads in the defaults from an XML file.
*/
public void loadConfig() {
// Get SAX Parser Factory
SAXParserFactory factory = SAXParserFactory.newInstance();
// Turn on validation, and turn off namespaces
factory.setValidating(false);
factory.setNamespaceAware(false);
try {
SAXParser parser = factory.newSAXParser();
InputStream stream = getClass().getClassLoader()
.getResourceAsStream(DEFAULT_CONFIG);
parser.parse(stream, new PreferenceHandler());
} catch (Exception e) {
LOGGER.log(Level.SEVERE, ERR_UNABLE_TO_LOAD_XML
+ STR_SPACE
+ DEFAULT_CONFIG);
LOGGER.log(Level.SEVERE, e.getMessage());
System.exit(INT_ERROR);
}
}
/**
* Returns the localized preference.
*
* @param KEY is the key to search for
* @return the value for that key
*/
public static String getLocalizedName(final String KEY) {
return rb.getResourceString(KEY);
}
/**
* Returns the default value for the key
*
* @param KEY key to store properties with in the preferences
* @return the value for that KEY
*/
private String getDefaultValue(final String KEY) {
if (MEC_SETTINGS.containsKey(KEY)) {
String value = (String) MEC_SETTINGS.get(KEY);
value = value.trim();
if (0 != value.length())
return value;
}
if (KEY.equals(FRAME_X)) {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension dialogSize = new Dimension(
Integer.parseInt(getDefaultValue(FRAME_WIDTH)),
Integer.parseInt(getDefaultValue(FRAME_HEIGHT)));
return (String.valueOf((screenSize.width - dialogSize.width) / 2));
}
if (KEY.equals(FRAME_Y)) {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension dialogSize = new Dimension(
Integer.parseInt(getDefaultValue(FRAME_WIDTH)),
Integer.parseInt(getDefaultValue(FRAME_HEIGHT)));
return (String.valueOf((screenSize.height - dialogSize.height) / 2));
}
if (KEY.equals(FRAME_WIDTH)) {
return (STR_EIGHT_HUNDRED);
}
if (KEY.equals(FRAME_HEIGHT)) {
return (STR_SIX_HUNDRED);
}
//language used for the localization
if (KEY.equals(LANGUAGE)) {
if (Locale.getDefault().equals(Locale.GERMANY)) {
return (STR_DE);
}
//default is always english
return (STR_EN);
}
//RMI port for client-server communication
if (KEY.equals(SERVER_RMI_PORT)) {
return (STR_ONEZERONINENINE);
}
//DB port for the server
if (KEY.equals(SERVER_DB_PORT)) {
return (STR_QUAD_THREE);
}
//RMI service provided by the rmi server
if (KEY.equals(SERVER_RMI_SERVICE)) {
return (STR_MECAS2);
}
//server to connect to by default
if (KEY.equals(SERVER_HOST)) {
return (STR_LOCALHOST);
}
//message part directory
if (KEY.equals(DIR_MSG)) {
return (new File(System.getProperty(STR_USRDIR)).getAbsolutePath()
+ File.separator + STR_MESSAGES);
}
if (KEY.equals(KEYSTORE_HTTPS_SEND)) {
return (STR_KEYSTORE_PATH);
}
if (KEY.equals(KEYSTORE_HTTPS_SEND_PASS)) {
return ("changeit");
}
if (KEY.equals(PROXY_HOST)) {
return ("localhost");
}
if (KEY.equals(PROXY_PORT)) {
return ("8118");
}
if (KEY.equals(AUTH_PROXY_PASS)) {
return ("mypass");
}
if (KEY.equals(AUTH_PROXY_USER)) {
return ("myuser");
}
if (KEY.equals(AUTH_PROXY_USE)) {
return ("FALSE");
}
if (KEY.equals(PROXY_USE)) {
return ("FALSE");
}
if (KEY.equals(KEYSTORE_PASS)) {
return ("test");
}
//30 minutes
if (KEY.equals(ASYNC_MDN_TIMEOUT)) {
return ("30");
}
if (KEY.equals(AUTO_MSG_DELETE)) {
return ("TRUE");
}
if (KEY.equals(AUTO_MSG_DELETE_LOG)) {
return ("TRUE");
}
if (KEY.equals(AUTO_MSG_DELETE_OLDERTHAN)) {
return ("5");
}
if (KEY.equals(JNDI_PORT)) {
return ("16423");
}
if (KEY.equals(MQ_PROXY_PORT)) {
System.out.println("No override for : " + KEY);
return ("16023");
}
if (KEY.equals(RECEIPT_PARTNER_SUBDIR)) {
return ("FALSE");
}
if (KEY.equals(CLIENTSERVER_COMM_PORT)) {
return ("1235");
}
if (KEY.equals(HTTP_SEND_TIMEOUT)) {
return ("5000");
}
throw new IllegalArgumentException("No defaults defined for prefs key "
+ KEY + " in " + this.getClass().getName());
}
/**
* Returns a single string value from the preferences or the default
* if it is not found
*
* @param KEY one of the class internal constants
*/
public String get(final String KEY) {
return (this.preferences.get(KEY, this.getDefaultValue(KEY)));
}
/**
* Stores a value in the preferences. If the passed value is null or an
* empty string the key-value pair will be deleted from the registry.
*
* @param KEY Key as defined in this class
* @param value value to set
*/
public void put(final String KEY, String value) {
if (value == null || value.length() == 0) {
this.preferences.remove(KEY);
} else {
this.preferences.put(KEY, value);
}
try {
this.preferences.flush();
} catch (BackingStoreException ignore) {
}
}
/**
* Puts a value to the preferences and stores the prefs
*
* @param KEY Key as defined in this class
* @param value value to set
*/
public void putInt(final String KEY, int value) {
this.preferences.putInt(KEY, value);
try {
this.preferences.flush();
} catch (BackingStoreException ignore) {
}
}
/**
* Returns the value for the asked key, if noen is defined it returns
* the default value
*/
public int getInt(final String KEY) {
return preferences.getInt(KEY, Integer.parseInt(getDefaultValue(KEY)));
}
/**
* Puts a value to the preferences and stores the prefs
*
* @param KEY Key as defined in this class
* @param value value to set
*/
public void putBoolean(final String KEY, boolean value) {
this.preferences.putBoolean(KEY, value);
try {
this.preferences.flush();
} catch (BackingStoreException ignore) {
}
}
/**
* Returns the value for the asked key.
}
}
/**
* Returns the value for the asked key, if noen is defined it returns
* the default value
*/
public int getInt(final String KEY) {
return preferences.getInt(KEY, Integer.parseInt(getDefaultValue(KEY)));
}
/**
* Puts a value to the preferences and stores the prefs
*
* @param KEY Key as defined in this class
* @param value value to set
*/
public void putBoolean(final String KEY, boolean value) {
this.preferences.putBoolean(KEY, value);
try {
this.preferences.flush();
} catch (BackingStoreException ignore) {
}
}
/**
* Returns the value for the asked key.
* if non is defined it returns the default value
*
* @param KEY is the key you want to check
* @return the boolean flag indicating if key exists.
*/
public boolean getBoolean(final String KEY) {
return (this.preferences.getBoolean(KEY,
Boolean.parseBoolean(getDefaultValue(KEY))));
}
/**
* Returns the value for the asked key.
* if there is no match, it returns the second parameter value
*
* @param KEY is the key to look for
* @param
* @return the value or the default
*/
public boolean getBoolean(final String KEY, final boolean defaultValue) {
return (preferences.getBoolean(KEY, defaultValue));
}
/**
* Returns the OS of the actual installation
*/
private int getOS() {
if (this.os.toLowerCase().startsWith(STR_WIN)) {
return (this.OS_WIN);
} else {
return (this.OS_OTHER);
}
}
}
You also have to edit deployment descriptor in jetty to match ports... here is my "config" file from ONE of the deployments.
<?xml version="1.0" encoding="UTF-8"?>
1138
1122
3331
16421
12023