XMLServerConfiguration.java 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022
  1. /*
  2. * Copyright (C) 2006-2010 Alfresco Software Limited.
  3. *
  4. * This file is part of Alfresco
  5. *
  6. * Alfresco is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Alfresco is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package org.alfresco.jlan.app;
  20. import java.io.File;
  21. import java.io.IOException;
  22. import java.net.InetAddress;
  23. import java.net.UnknownHostException;
  24. import java.security.KeyStore;
  25. import java.security.KeyStoreException;
  26. import java.util.StringTokenizer;
  27. import org.alfresco.jlan.ftp.FTPConfigSection;
  28. import org.alfresco.jlan.ftp.FTPPath;
  29. import org.alfresco.jlan.ftp.FTPSiteInterface;
  30. import org.alfresco.jlan.ftp.InvalidPathException;
  31. import org.alfresco.jlan.oncrpc.nfs.NFSConfigSection;
  32. import org.alfresco.jlan.server.config.InvalidConfigurationException;
  33. import org.alfresco.jlan.server.filesys.cache.hazelcast.ClusterConfigSection;
  34. import org.springframework.extensions.config.ConfigElement;
  35. import org.w3c.dom.Document;
  36. import org.w3c.dom.Element;
  37. import org.w3c.dom.NodeList;
  38. /**
  39. * XML File Server Configuration Class
  40. *
  41. * <p>
  42. * XML implementation of the SMB server configuration. Save/load the server configuration to an XML
  43. * format file using the DOM API.
  44. *
  45. * @author gkspencer
  46. */
  47. public class XMLServerConfiguration extends CifsOnlyXMLServerConfiguration {
  48. // Constants
  49. //
  50. // Default FTP server port and anonymous account name
  51. private static final int DEFAULT_FTP_PORT = 21;
  52. private static final String ANONYMOUS_FTP_ACCOUNT = "anonymous";
  53. // FTP server debug type strings
  54. private static final String m_ftpDebugStr[] = { "STATE", "RXDATA", "TXDATA", "DUMPDATA", "SEARCH", "INFO", "FILE", "FILEIO",
  55. "ERROR", "PKTTYPE", "TIMING", "DATAPORT", "DIRECTORY", "SSL" };
  56. // NFS server debug type strings
  57. private static final String m_nfsDebugStr[] = { "RXDATA", "TXDATA", "DUMPDATA", "SEARCH", "INFO", "FILE", "FILEIO", "ERROR",
  58. "TIMING", "DIRECTORY", "SESSION" };
  59. // Global server enable flags
  60. private boolean m_cifsEnabled;
  61. private boolean m_ftpEnabled;
  62. private boolean m_nfsEnabled;
  63. /**
  64. * Default constructor
  65. */
  66. public XMLServerConfiguration() {
  67. super();
  68. }
  69. /**
  70. * Load the configuration from the specified document
  71. *
  72. * @param doc Document
  73. * @exception IOException
  74. * @exception InvalidConfigurationException
  75. */
  76. public void loadConfiguration(Document doc)
  77. throws IOException, InvalidConfigurationException {
  78. // Reset the current configuration to the default settings
  79. removeAllConfigSections();
  80. // Parse the XML configuration document
  81. try {
  82. // Access the root of the XML document, get a list of the child nodes
  83. Element root = doc.getDocumentElement();
  84. NodeList childNodes = root.getChildNodes();
  85. // Process the cluster settings element
  86. procClusterElement(findChildNode("cluster", childNodes));
  87. // Process the debug settings element
  88. procDebugElement(findChildNode("debug", childNodes));
  89. // Process the main server enable element
  90. procServersElement(findChildNode("servers", childNodes));
  91. // Process the core server configuration settings
  92. procServerCoreElement(findChildNode("server-core", childNodes));
  93. // Process the global configuration settings
  94. procGlobalElement(findChildNode("global", childNodes));
  95. // Process the security element
  96. procSecurityElement(findChildNode("security", childNodes));
  97. // Process the shares element
  98. procSharesElement(findChildNode("shares", childNodes));
  99. // Process the SMB server specific settings
  100. if ( isCIFSServerEnabled())
  101. procSMBServerElement(findChildNode("SMB", childNodes));
  102. // Process the FTP server configuration
  103. if ( isFTPServerEnabled())
  104. procFTPServerElement(findChildNode("FTP", childNodes));
  105. // Process the NFS server configuration
  106. if ( isNFSServerEnabled())
  107. procNFSServerElement(findChildNode("NFS", childNodes));
  108. }
  109. catch (Exception ex) {
  110. // Rethrow the exception as a configuration exeception
  111. throw new InvalidConfigurationException("XML error", ex);
  112. }
  113. }
  114. /**
  115. * Check if the CIFS server is enabled
  116. *
  117. * @return boolean
  118. */
  119. public final boolean isCIFSServerEnabled() {
  120. return m_cifsEnabled;
  121. }
  122. /**
  123. * Check if the FTP server is enabled
  124. *
  125. * @return boolean
  126. */
  127. public final boolean isFTPServerEnabled() {
  128. return m_ftpEnabled;
  129. }
  130. /**
  131. * Check if the NFS server is enabled
  132. *
  133. * @return boolean
  134. */
  135. public final boolean isNFSServerEnabled() {
  136. return m_nfsEnabled;
  137. }
  138. /**
  139. * Process the servers XML element
  140. *
  141. * @param servers Element
  142. * @exception InvalidConfigurationException
  143. */
  144. protected final void procServersElement(Element servers)
  145. throws InvalidConfigurationException {
  146. // Check if the servers element has been specified, if not then this is an old format
  147. // configuration
  148. if ( servers != null) {
  149. // Check if the SMB server is enabled
  150. if ( findChildNode("SMB", servers.getChildNodes()) != null || findChildNode("CIFS", servers.getChildNodes()) != null)
  151. m_cifsEnabled = true;
  152. // Check if the FTP server is enabled
  153. if ( findChildNode("FTP", servers.getChildNodes()) != null)
  154. m_ftpEnabled = true;
  155. // Check if the NFS server is enabled
  156. if ( findChildNode("NFS", servers.getChildNodes()) != null)
  157. m_nfsEnabled = true;
  158. }
  159. }
  160. /**
  161. * Process the FTP server XML element
  162. *
  163. * @param ftp Element
  164. * @exception InvalidConfigurationException
  165. */
  166. protected final void procFTPServerElement(Element ftp)
  167. throws InvalidConfigurationException {
  168. // Check if the FTP element is valid, if not then disable the FTP server
  169. if ( ftp == null) {
  170. // Check if the FTP server is enabled, if so then there must be an FTP configuration
  171. // section
  172. if ( isFTPServerEnabled())
  173. throw new InvalidConfigurationException("FTP server enabled, but not configured");
  174. return;
  175. }
  176. // Create the FTP server configuration section
  177. FTPConfigSection ftpConfig = new FTPConfigSection(this);
  178. // Check for a bind address
  179. Element elem = findChildNode("bindto", ftp.getChildNodes());
  180. if ( elem != null) {
  181. // Check if the network adapter name has been specified
  182. if ( elem.hasAttribute("adapter")) {
  183. // Get the IP address for the adapter
  184. InetAddress bindAddr = parseAdapterName(elem.getAttribute("adapter"));
  185. // Set the bind address for the server
  186. ftpConfig.setFTPBindAddress(bindAddr);
  187. }
  188. else {
  189. // Validate the bind address
  190. String bindText = getText(elem);
  191. try {
  192. // Check the bind address
  193. InetAddress bindAddr = InetAddress.getByName(bindText);
  194. // Set the bind address for the FTP server
  195. ftpConfig.setFTPBindAddress(bindAddr);
  196. }
  197. catch (UnknownHostException ex) {
  198. throw new InvalidConfigurationException(ex.toString());
  199. }
  200. }
  201. }
  202. // Check for an FTP server port
  203. elem = findChildNode("port", ftp.getChildNodes());
  204. if ( elem != null) {
  205. try {
  206. ftpConfig.setFTPPort(Integer.parseInt(getText(elem)));
  207. if ( ftpConfig.getFTPPort() <= 0 || ftpConfig.getFTPPort() >= 65535)
  208. throw new InvalidConfigurationException("FTP server port out of valid range");
  209. }
  210. catch (NumberFormatException ex) {
  211. throw new InvalidConfigurationException("Invalid FTP server port");
  212. }
  213. }
  214. else {
  215. // Use the default FTP port
  216. ftpConfig.setFTPPort(DEFAULT_FTP_PORT);
  217. }
  218. // Check if anonymous login is allowed
  219. elem = findChildNode("allowAnonymous", ftp.getChildNodes());
  220. if ( elem != null) {
  221. // Enable anonymous login to the FTP server
  222. ftpConfig.setAllowAnonymousFTP(true);
  223. // Check if an anonymous account has been specified
  224. String anonAcc = elem.getAttribute("user");
  225. if ( anonAcc != null && anonAcc.length() > 0) {
  226. // Set the anonymous account name
  227. ftpConfig.setAnonymousFTPAccount(anonAcc);
  228. // Check if the anonymous account name is valid
  229. if ( ftpConfig.getAnonymousFTPAccount() == null || ftpConfig.getAnonymousFTPAccount().length() == 0)
  230. throw new InvalidConfigurationException("Anonymous FTP account invalid");
  231. }
  232. else {
  233. // Use the default anonymous account name
  234. ftpConfig.setAnonymousFTPAccount(ANONYMOUS_FTP_ACCOUNT);
  235. }
  236. }
  237. else {
  238. // Disable anonymous logins
  239. ftpConfig.setAllowAnonymousFTP(false);
  240. }
  241. // Check if a root path has been specified
  242. elem = findChildNode("rootDirectory", ftp.getChildNodes());
  243. if ( elem != null) {
  244. // Get the root path
  245. String rootPath = getText(elem);
  246. // Validate the root path
  247. try {
  248. // Parse the path
  249. new FTPPath(rootPath);
  250. // Set the root path
  251. ftpConfig.setFTPRootPath(rootPath);
  252. }
  253. catch (InvalidPathException ex) {
  254. throw new InvalidConfigurationException("Invalid FTP root directory, " + rootPath);
  255. }
  256. }
  257. // Check if a data port range has been specified
  258. elem = findChildNode("dataPorts", ftp.getChildNodes());
  259. if ( elem != null) {
  260. // Check for the from port range value
  261. int rangeFrom = -1;
  262. int rangeTo = -1;
  263. String rangeStr = elem.getAttribute("rangeFrom");
  264. if ( rangeStr != null && rangeStr.length() > 0) {
  265. // Validate the range string
  266. try {
  267. rangeFrom = Integer.parseInt(rangeStr);
  268. }
  269. catch (NumberFormatException ex) {
  270. throw new InvalidConfigurationException("Invalid FTP rangeFrom value, " + rangeStr);
  271. }
  272. }
  273. // Check for the to port range value
  274. rangeStr = elem.getAttribute("rangeTo");
  275. if ( rangeStr != null && rangeStr.length() > 0) {
  276. // Validate the range string
  277. try {
  278. rangeTo = Integer.parseInt(rangeStr);
  279. }
  280. catch (NumberFormatException ex) {
  281. throw new InvalidConfigurationException("Invalid FTP rangeTo value, " + rangeStr);
  282. }
  283. }
  284. // Validate the data port range values
  285. if ( rangeFrom == -1 || rangeTo == -1)
  286. throw new InvalidConfigurationException("FTP data port range from/to must be specified");
  287. if ( rangeFrom < 1024 || rangeFrom > 65535)
  288. throw new InvalidConfigurationException("Invalid FTP data port rangeFrom value, " + rangeFrom);
  289. if ( rangeTo < 1024 || rangeTo > 65535)
  290. throw new InvalidConfigurationException("Invalid FTP data port rangeTo value, " + rangeTo);
  291. if ( rangeFrom >= rangeTo)
  292. throw new InvalidConfigurationException("Invalid FTP data port range, " + rangeFrom + "-" + rangeTo);
  293. // Set the FTP data port range
  294. ftpConfig.setFTPDataPortLow(rangeFrom);
  295. ftpConfig.setFTPDataPortHigh(rangeTo);
  296. }
  297. // Check if FTP debug is enabled
  298. elem = findChildNode("debug", ftp.getChildNodes());
  299. if ( elem != null) {
  300. // Check for FTP debug flags
  301. String flags = elem.getAttribute("flags");
  302. int ftpDbg = 0;
  303. if ( flags != null) {
  304. // Parse the flags
  305. flags = flags.toUpperCase();
  306. StringTokenizer token = new StringTokenizer(flags, ",");
  307. while (token.hasMoreTokens()) {
  308. // Get the current debug flag token
  309. String dbg = token.nextToken().trim();
  310. // Find the debug flag name
  311. int idx = 0;
  312. while (idx < m_ftpDebugStr.length && m_ftpDebugStr[idx].equalsIgnoreCase(dbg) == false)
  313. idx++;
  314. if ( idx >= m_ftpDebugStr.length)
  315. throw new InvalidConfigurationException("Invalid FTP debug flag, " + dbg);
  316. // Set the debug flag
  317. ftpDbg += 1 << idx;
  318. }
  319. }
  320. // Set the FTP debug flags
  321. ftpConfig.setFTPDebug(ftpDbg);
  322. }
  323. // Check if a site interface has been specified
  324. elem = findChildNode("siteInterface", ftp.getChildNodes());
  325. if ( elem != null) {
  326. // Get the site interface class name
  327. Element classElem = findChildNode("class", elem.getChildNodes());
  328. if ( classElem == null)
  329. throw new InvalidConfigurationException("Class not specified for FTP site interface");
  330. String siteClass = getText(classElem);
  331. // Validate the site interface class
  332. try {
  333. // Load the driver class
  334. Object siteObj = Class.forName(siteClass).newInstance();
  335. if ( siteObj instanceof FTPSiteInterface) {
  336. // Initialize the site interface
  337. ConfigElement params = buildConfigElement(elem);
  338. FTPSiteInterface ftpSiteInterface = (FTPSiteInterface) siteObj;
  339. ftpSiteInterface.initializeSiteInterface(this, params);
  340. // Set the site interface
  341. ftpConfig.setFTPSiteInterface(ftpSiteInterface);
  342. }
  343. }
  344. catch (ClassNotFoundException ex) {
  345. throw new InvalidConfigurationException("FTP site interface class " + siteClass + " not found");
  346. }
  347. catch (Exception ex) {
  348. throw new InvalidConfigurationException("FTP site interface setup error, " + ex.toString());
  349. }
  350. }
  351. // Check if an authenticator has been specified
  352. elem = findChildNode("authenticator", ftp.getChildNodes());
  353. if ( elem != null) {
  354. // Get the FTP authenticator class
  355. Element classElem = findChildNode("class", elem.getChildNodes());
  356. if ( classElem == null)
  357. throw new InvalidConfigurationException("FTP Authenticator class not specified");
  358. // Get the parameters for the FTP authenticator class
  359. ConfigElement params = buildConfigElement(elem);
  360. ftpConfig.setAuthenticator(getText(classElem), params);
  361. }
  362. // FTPS parameter parsing
  363. //
  364. // Check if a key store path has been specified
  365. elem = findChildNode("keyStore", ftp.getChildNodes());
  366. if ( elem != null) {
  367. // Get the path to the key store, check that the file exists
  368. String keyStorePath = getText( elem);
  369. File keyStoreFile = new File( keyStorePath);
  370. if ( keyStoreFile.exists() == false)
  371. throw new InvalidConfigurationException("FTPS key store file does not exist, " + keyStorePath);
  372. else if ( keyStoreFile.isDirectory())
  373. throw new InvalidConfigurationException("FTPS key store path is a directory, " + keyStorePath);
  374. // Set the key store path
  375. ftpConfig.setKeyStorePath( keyStorePath);
  376. }
  377. // Check if a key store type has been specified
  378. elem = findChildNode("keyStoreType", ftp.getChildNodes());
  379. if ( elem != null) {
  380. // Get the key store type, and validate
  381. String keyStoreType = getText( elem);
  382. if ( keyStoreType == null || keyStoreType.length() == 0)
  383. throw new InvalidConfigurationException("FTPS key store type is invalid");
  384. try {
  385. KeyStore.getInstance( keyStoreType);
  386. }
  387. catch ( KeyStoreException ex) {
  388. throw new InvalidConfigurationException("FTPS key store type is invalid, " + keyStoreType, ex);
  389. }
  390. // Set the key store type
  391. ftpConfig.setKeyStoreType( keyStoreType);
  392. }
  393. // Check if the key store passphrase has been specified
  394. elem = findChildNode("keyStorePassphrase", ftp.getChildNodes());
  395. if ( elem != null) {
  396. // Set the key store passphrase
  397. ftpConfig.setKeyStorePassphrase( getText( elem));
  398. }
  399. // Check if the trust store path has been specified
  400. elem = findChildNode("trustStore", ftp.getChildNodes());
  401. if ( elem != null) {
  402. // Get the path to the trust store, check that the file exists
  403. String trustStorePath = getText( elem);
  404. File trustStoreFile = new File( trustStorePath);
  405. if ( trustStoreFile.exists() == false)
  406. throw new InvalidConfigurationException("FTPS trust store file does not exist, " + trustStorePath);
  407. else if ( trustStoreFile.isDirectory())
  408. throw new InvalidConfigurationException("FTPS trust store path is a directory, " + trustStorePath);
  409. // Set the trust store path
  410. ftpConfig.setTrustStorePath( trustStorePath);
  411. }
  412. // Check if a trust store type has been specified
  413. elem = findChildNode("trustStoreType", ftp.getChildNodes());
  414. if ( elem != null) {
  415. // Get the trust store type, and validate
  416. String trustStoreType = getText( elem);
  417. if ( trustStoreType == null || trustStoreType.length() == 0)
  418. throw new InvalidConfigurationException("FTPS trust store type is invalid");
  419. try {
  420. KeyStore.getInstance( trustStoreType);
  421. }
  422. catch ( KeyStoreException ex) {
  423. throw new InvalidConfigurationException("FTPS trust store type is invalid, " + trustStoreType, ex);
  424. }
  425. // Set the trust store type
  426. ftpConfig.setTrustStoreType( trustStoreType);
  427. }
  428. // Check if the trust store passphrase has been specified
  429. elem = findChildNode("trustStorePassphrase", ftp.getChildNodes());
  430. if ( elem != null) {
  431. // Set the key store passphrase
  432. ftpConfig.setTrustStorePassphrase( getText( elem));
  433. }
  434. // Check if only secure sessions should be allowed to logon
  435. elem = findChildNode("requireSecureSession", ftp.getChildNodes());
  436. if ( elem != null) {
  437. // Only allow secure sessions to logon to the FTP server
  438. ftpConfig.setRequireSecureSession( true);
  439. }
  440. // Check that all the required FTPS parameters have been set
  441. // MNT-7301 FTPS server requires unnecessarly to have a trustStore while a keyStore should be sufficient
  442. if ( ftpConfig.getKeyStorePath() != null) {
  443. // Make sure all parameters are set
  444. if ( ftpConfig.getKeyStorePath() == null)
  445. throw new InvalidConfigurationException("FTPS configuration requires keyStore to be set");
  446. }
  447. // Check if SSLEngine debug output should be enabled
  448. elem = findChildNode("sslEngineDebug", ftp.getChildNodes());
  449. if ( elem != null) {
  450. // Enable SSLEngine debug output
  451. System.setProperty("javax.net.debug", "ssl,handshake");
  452. }
  453. }
  454. /**
  455. * Process the NFS server XML element
  456. *
  457. * @param nfs Element
  458. * @exception InvalidConfigurationException
  459. */
  460. protected final void procNFSServerElement(Element nfs)
  461. throws InvalidConfigurationException {
  462. // Check if the NFS element is valid
  463. if ( nfs == null)
  464. return;
  465. // Create the NFS server configuration section
  466. NFSConfigSection nfsConfig = new NFSConfigSection(this);
  467. // Check if the port mapper is enabled
  468. if ( findChildNode("enablePortMapper", nfs.getChildNodes()) != null)
  469. nfsConfig.setNFSPortMapper(true);
  470. // Check for the thread pool size
  471. Element elem = findChildNode("ThreadPool", nfs.getChildNodes());
  472. // Check for the old TCPThreadPool value if the new value is not available
  473. if ( elem == null)
  474. elem = findChildNode("TCPThreadPool", nfs.getChildNodes());
  475. if ( elem != null) {
  476. try {
  477. // Convert the pool size value
  478. int poolSize = Integer.parseInt(getText(elem));
  479. // Range check the pool size value
  480. if ( poolSize < 4)
  481. throw new InvalidConfigurationException("NFS thread pool size is below minimum of 4");
  482. // Set the thread pool size
  483. nfsConfig.setNFSThreadPoolSize(poolSize);
  484. }
  485. catch (NumberFormatException ex) {
  486. throw new InvalidConfigurationException("Invalid NFS thread pool size setting, " + getText(elem));
  487. }
  488. }
  489. // NFS packet pool size
  490. elem = findChildNode("PacketPool", nfs.getChildNodes());
  491. if ( elem != null) {
  492. try {
  493. // Convert the packet pool size value
  494. int pktPoolSize = Integer.parseInt(getText(elem));
  495. // Range check the pool size value
  496. if ( pktPoolSize < 10)
  497. throw new InvalidConfigurationException("NFS packet pool size is below minimum of 10");
  498. if ( pktPoolSize < nfsConfig.getNFSThreadPoolSize() + 1)
  499. throw new InvalidConfigurationException("NFS packet pool must be at least thread pool size plus one");
  500. // Set the packet pool size
  501. nfsConfig.setNFSPacketPoolSize(pktPoolSize);
  502. }
  503. catch (NumberFormatException ex) {
  504. throw new InvalidConfigurationException("Invalid NFS packet pool size setting, " + getText(elem));
  505. }
  506. }
  507. // Check for a port mapper server port
  508. if ( findChildNode("disablePortMapperRegistration", nfs.getChildNodes()) != null) {
  509. // Disable port mapper registration for the mount/NFS servers
  510. nfsConfig.setPortMapperPort( -1);
  511. }
  512. else {
  513. elem = findChildNode("PortMapperPort", nfs.getChildNodes());
  514. if ( elem != null) {
  515. try {
  516. nfsConfig.setPortMapperPort(Integer.parseInt(getText(elem)));
  517. if ( nfsConfig.getPortMapperPort() <= 0 || nfsConfig.getPortMapperPort() >= 65535)
  518. throw new InvalidConfigurationException("Port mapper server port out of valid range");
  519. }
  520. catch (NumberFormatException ex) {
  521. throw new InvalidConfigurationException("Invalid port mapper server port");
  522. }
  523. }
  524. }
  525. // Check for a mount server port
  526. elem = findChildNode("MountServerPort", nfs.getChildNodes());
  527. if ( elem != null) {
  528. try {
  529. nfsConfig.setMountServerPort(Integer.parseInt(getText(elem)));
  530. if ( nfsConfig.getMountServerPort() <= 0 || nfsConfig.getMountServerPort() >= 65535)
  531. throw new InvalidConfigurationException("Mount server port out of valid range");
  532. }
  533. catch (NumberFormatException ex) {
  534. throw new InvalidConfigurationException("Invalid mount server port");
  535. }
  536. }
  537. // Check for an NFS server port
  538. elem = findChildNode("NFSServerPort", nfs.getChildNodes());
  539. if ( elem != null) {
  540. try {
  541. nfsConfig.setNFSServerPort(Integer.parseInt(getText(elem)));
  542. if ( nfsConfig.getNFSServerPort() <= 0 || nfsConfig.getNFSServerPort() >= 65535)
  543. throw new InvalidConfigurationException("NFS server port out of valid range");
  544. }
  545. catch (NumberFormatException ex) {
  546. throw new InvalidConfigurationException("Invalid NFS server port");
  547. }
  548. }
  549. // Check for an RPC registration port
  550. elem = findChildNode("RPCRegisterPort", nfs.getChildNodes());
  551. if ( elem != null) {
  552. try {
  553. nfsConfig.setRPCRegistrationPort(Integer.parseInt(getText(elem)));
  554. if ( nfsConfig.getRPCRegistrationPort() <= 0 || nfsConfig.getRPCRegistrationPort() >= 65535)
  555. throw new InvalidConfigurationException("RPC registration port out of valid range");
  556. }
  557. catch (NumberFormatException ex) {
  558. throw new InvalidConfigurationException("Invalid RPC registration port");
  559. }
  560. }
  561. // Check if an RPC authenticator has been specified
  562. elem = findChildNode("rpcAuthenticator", nfs.getChildNodes());
  563. if ( elem != null) {
  564. // Get the RPC authenticator class
  565. Element classElem = findChildNode("class", elem.getChildNodes());
  566. if ( classElem == null)
  567. throw new InvalidConfigurationException("RPC Authenticator class not specified");
  568. // Get the parameters for the RPC authenticator class
  569. ConfigElement params = buildConfigElement(elem);
  570. nfsConfig.setRpcAuthenticator(getText(classElem), params);
  571. }
  572. else {
  573. // Use the null RPC authenticator as the default
  574. nfsConfig.setRpcAuthenticator( "org.alfresco.jlan.oncrpc.DefaultRpcAuthenticator", new ConfigElement( "", ""));
  575. }
  576. // Check if NFS debug is enabled
  577. elem = findChildNode("debug", nfs.getChildNodes());
  578. if ( elem != null) {
  579. // Check for NFS debug flags
  580. String flags = elem.getAttribute("flags");
  581. int nfsDbg = 0;
  582. if ( flags != null) {
  583. // Parse the flags
  584. flags = flags.toUpperCase();
  585. StringTokenizer token = new StringTokenizer(flags, ",");
  586. while (token.hasMoreTokens()) {
  587. // Get the current debug flag token
  588. String dbg = token.nextToken().trim();
  589. // Find the debug flag name
  590. int idx = 0;
  591. while (idx < m_nfsDebugStr.length && m_nfsDebugStr[idx].equalsIgnoreCase(dbg) == false)
  592. idx++;
  593. if ( idx >= m_nfsDebugStr.length)
  594. throw new InvalidConfigurationException("Invalid NFS debug flag, " + dbg);
  595. // Set the debug flag
  596. nfsDbg += 1 << idx;
  597. }
  598. }
  599. // Set the NFS debug flags
  600. nfsConfig.setNFSDebug(nfsDbg);
  601. }
  602. // Check if mount server debug output is enabled
  603. elem = findChildNode("mountServerDebug", nfs.getChildNodes());
  604. if ( elem != null)
  605. nfsConfig.setMountServerDebug(true);
  606. // Check if port mapper debug output is enabled
  607. elem = findChildNode("portMapperDebug", nfs.getChildNodes());
  608. if ( elem != null)
  609. nfsConfig.setPortMapperDebug(true);
  610. // Check if the file cache timers have been specified
  611. elem = findChildNode("FileCache", nfs.getChildNodes());
  612. if ( elem != null) {
  613. try {
  614. // Check for a single value or I/O and close timer values
  615. String numVal = getText(elem);
  616. long cacheIOTimer = -1;
  617. long cacheCloseTimer = -1;
  618. int pos = numVal.indexOf(':');
  619. if ( pos == -1) {
  620. // Only change the I/O timer
  621. cacheIOTimer = Integer.parseInt(numVal);
  622. }
  623. else {
  624. // Split the string value into read and write values, and convert to integers
  625. String val = numVal.substring(0, pos);
  626. cacheIOTimer = Integer.parseInt(val);
  627. val = numVal.substring(pos + 1);
  628. cacheCloseTimer = Integer.parseInt(val);
  629. }
  630. // Range check the I/O timer
  631. if ( cacheIOTimer < 0 || cacheIOTimer > 30)
  632. throw new InvalidConfigurationException("Invalid NFS file cache I/O timer value, " + cacheIOTimer);
  633. else {
  634. // Convert the timer to milliseconds
  635. nfsConfig.setNFSFileCacheIOTimer(cacheIOTimer * 1000L);
  636. }
  637. // Range check the close timer, if specified
  638. if ( cacheCloseTimer != -1) {
  639. if ( cacheCloseTimer < 0 || cacheCloseTimer > 120)
  640. throw new InvalidConfigurationException("Invalid NFS file cache close timer value, " + cacheCloseTimer);
  641. else {
  642. // Convert the timer to milliseconds
  643. nfsConfig.setNFSFileCacheCloseTimer(cacheCloseTimer * 1000L);
  644. }
  645. }
  646. }
  647. catch (NumberFormatException ex) {
  648. throw new InvalidConfigurationException("Invalid NFS file cache timer value, " + ex.toString());
  649. }
  650. }
  651. // Check if NFS file cache debug output is enabled
  652. if ( findChildNode("fileCacheDebug", nfs.getChildNodes()) != null)
  653. nfsConfig.setNFSFileCacheDebug(true);
  654. }
  655. /**
  656. * Process the servers XML element
  657. *
  658. * @param cluster Element
  659. * @exception InvalidConfigurationException
  660. */
  661. protected final void procClusterElement(Element cluster)
  662. throws InvalidConfigurationException {
  663. // Check if the cluster element has been specified
  664. if ( cluster != null) {
  665. // Check if the Hazelcast classes are available on the classpath
  666. try {
  667. // Check for various Hazelcast classes
  668. Class.forName( "com.hazelcast.core.HazelcastInstance");
  669. Class.forName( "com.hazelcast.core.IMap");
  670. Class.forName( "com.hazelcast.core.ITopic");
  671. // Check for the cluster configuration section
  672. Class.forName( "org.alfresco.jlan.server.filesys.cache.hazelcast.ClusterConfigSection");
  673. }
  674. catch ( ClassNotFoundException ex) {
  675. throw new InvalidConfigurationException( "Hazelcast classes not found on the classpath, required for cluster support");
  676. }
  677. // Create the cluster configuration section
  678. ClusterConfigSection clusterConfig = new ClusterConfigSection( this);
  679. // Get the path to the HazelCast configuration file
  680. Element elem = findChildNode("configFile", cluster.getChildNodes());
  681. if ( elem != null) {
  682. // Check that the configuration file exists, and is a file
  683. String configPath = getText( elem);
  684. try {
  685. File confFile = new File( configPath);
  686. if ( confFile.exists() == false)
  687. throw new InvalidConfigurationException( "HazelCast configuration file does not exist, " + configPath);
  688. if ( confFile.isDirectory())
  689. throw new InvalidConfigurationException( "HazelCast configuration file is a folder path, " + configPath);
  690. // Set the Hazelcast cluster configuration file location
  691. clusterConfig.setConfigFile( configPath);
  692. }
  693. catch ( Exception ex) {
  694. throw new InvalidConfigurationException( "HazelCast configuration file not valid", ex);
  695. }
  696. }
  697. else
  698. throw new InvalidConfigurationException( "HazelCast configuration file not specified");
  699. }
  700. }
  701. }