Java tutorial
/* * Copyright (C) 2005-2015 Alfresco Software Limited. * * This file is part of Alfresco * * Alfresco is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Alfresco is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. */ package org.alfresco.filesys.config; import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.NetworkInterface; import java.net.Socket; import java.net.SocketException; import java.net.UnknownHostException; import java.nio.charset.Charset; import java.nio.charset.IllegalCharsetNameException; import java.nio.charset.UnsupportedCharsetException; import java.security.KeyStore; import java.security.KeyStoreException; import java.util.EnumSet; import java.util.Enumeration; import java.util.List; import java.util.StringTokenizer; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.filesys.AbstractServerConfigurationBean; import org.alfresco.filesys.alfresco.AlfrescoContext; import org.alfresco.filesys.alfresco.ExtendedDiskInterface; import org.alfresco.filesys.config.acl.AccessControlListBean; import org.alfresco.filesys.repo.BufferedContentDiskDriver; import org.alfresco.filesys.repo.ContentContext; import org.alfresco.filesys.repo.ContentDiskDriver2; import org.alfresco.filesys.repo.LegacyFileStateDriver; import org.alfresco.filesys.repo.NonTransactionalRuleContentDiskDriver; import org.alfresco.jlan.ftp.FTPAuthenticator; import org.alfresco.jlan.ftp.FTPConfigSection; import org.alfresco.jlan.ftp.FTPPath; import org.alfresco.jlan.ftp.InvalidPathException; import org.alfresco.jlan.netbios.NetBIOSSession; import org.alfresco.jlan.netbios.RFCNetBIOSProtocol; import org.alfresco.jlan.netbios.win32.Win32NetBIOS; import org.alfresco.jlan.oncrpc.RpcAuthenticator; import org.alfresco.jlan.oncrpc.nfs.NFSConfigSection; import org.alfresco.jlan.server.auth.ICifsAuthenticator; import org.alfresco.jlan.server.auth.acl.AccessControlList; import org.alfresco.jlan.server.auth.passthru.DomainMapping; import org.alfresco.jlan.server.auth.passthru.RangeDomainMapping; import org.alfresco.jlan.server.auth.passthru.SubnetDomainMapping; import org.alfresco.jlan.server.config.CoreServerConfigSection; import org.alfresco.jlan.server.config.InvalidConfigurationException; import org.alfresco.jlan.server.config.SecurityConfigSection; import org.alfresco.jlan.server.core.DeviceContext; import org.alfresco.jlan.server.core.DeviceContextException; import org.alfresco.jlan.server.core.ShareMapper; import org.alfresco.jlan.server.core.ShareType; import org.alfresco.jlan.server.filesys.DiskDeviceContext; import org.alfresco.jlan.server.filesys.DiskSharedDevice; import org.alfresco.jlan.server.filesys.FilesystemsConfigSection; import org.alfresco.jlan.server.filesys.cache.FileStateLockManager; import org.alfresco.jlan.server.filesys.cache.StandaloneFileStateCache; import org.alfresco.jlan.server.filesys.cache.hazelcast.ClusterConfigSection; import org.alfresco.jlan.server.filesys.cache.hazelcast.HazelCastClusterFileStateCache; import org.alfresco.jlan.server.thread.ThreadRequestPool; import org.alfresco.jlan.smb.server.CIFSConfigSection; import org.alfresco.jlan.smb.server.VirtualCircuitList; import org.alfresco.jlan.util.IPAddress; import org.alfresco.jlan.util.MemorySize; import org.alfresco.jlan.util.Platform; import org.alfresco.jlan.util.StringList; import org.alfresco.jlan.util.X64; import org.alfresco.repo.management.subsystems.ActivateableBean; import org.springframework.beans.factory.DisposableBean; import org.springframework.extensions.config.element.GenericConfigElement; /** * Alfresco File Server Configuration Bean Class * <p> * Acts as an adaptor between JLAN's configuration requirements and the spring configuration of * the Alfresco filesystem subsystem. * <p> * Also contains an amount of initialisation logic. * * @author gkspencer * @author dward * @author mrogers */ public class ServerConfigurationBean extends AbstractServerConfigurationBean implements DisposableBean { private CIFSConfigBean cifsConfigBean; private FTPConfigBean ftpConfigBean; private NFSConfigBean nfsConfigBean; private List<DeviceContext> filesystemContexts; private SecurityConfigBean securityConfigBean; private CoreServerConfigBean coreServerConfigBean; private ThreadRequestPool threadPool; protected ClusterConfigBean clusterConfigBean; /** * Default constructor */ public ServerConfigurationBean() { super(""); } /** * Class constructor * * @param srvName * String */ public ServerConfigurationBean(String srvName) { super(srvName); } public void setCifsConfigBean(CIFSConfigBean cifsConfigBean) { this.cifsConfigBean = cifsConfigBean; } public void setFtpConfigBean(FTPConfigBean ftpConfigBean) { this.ftpConfigBean = ftpConfigBean; } public void setNfsConfigBean(NFSConfigBean nfsConfigBean) { this.nfsConfigBean = nfsConfigBean; } public void setFilesystemContexts(List<DeviceContext> filesystemContexts) { this.filesystemContexts = filesystemContexts; } public void setSecurityConfigBean(SecurityConfigBean securityConfigBean) { this.securityConfigBean = securityConfigBean; } public void setCoreServerConfigBean(CoreServerConfigBean coreServerConfigBean) { this.coreServerConfigBean = coreServerConfigBean; } public void setClusterConfigBean(ClusterConfigBean clusterConfigBean) { this.clusterConfigBean = clusterConfigBean; } /** * Process the CIFS server configuration */ protected void processCIFSServerConfig() { // If the configuration section is not valid then CIFS is disabled if (cifsConfigBean == null) { removeConfigSection(CIFSConfigSection.SectionName); return; } // Check if the server has been disabled if (!cifsConfigBean.getServerEnabled()) { removeConfigSection(CIFSConfigSection.SectionName); return; } // Before we go any further, let's make sure there's a compatible authenticator in the authentication chain. ICifsAuthenticator authenticator = cifsConfigBean.getAuthenticator(); if (authenticator == null || authenticator instanceof ActivateableBean && !((ActivateableBean) authenticator).isActive()) { logger.error("No enabled CIFS authenticator found in authentication chain. CIFS Server disabled"); removeConfigSection(CIFSConfigSection.SectionName); return; } // Create the CIFS server configuration section CIFSConfigSection cifsConfig = new CIFSConfigSection(this); try { // Check if native code calls should be disabled on Windows if (cifsConfigBean.getDisableNativeCode()) { // Disable native code calls so that the JNI DLL is not required cifsConfig.setNativeCodeDisabled(true); m_disableNativeCode = true; // Warning logger.warn("CIFS server native calls disabled, JNI code will not be used"); } // Get the network broadcast address // // Note: We need to set this first as the call to getLocalDomainName() may use a NetBIOS // name lookup, so the broadcast mask must be set before then. String broadcastAddess = cifsConfigBean.getBroadcastAddress(); if (broadcastAddess != null && broadcastAddess.length() > 0) { // Check if the broadcast mask is a valid numeric IP address if (IPAddress.isNumericAddress(broadcastAddess) == false) { throw new AlfrescoRuntimeException("CIFS Invalid broadcast mask, must be n.n.n.n format"); } // Set the network broadcast mask cifsConfig.setBroadcastMask(broadcastAddess); } // Get the terminal server address List<String> terminalServerList = cifsConfigBean.getTerminalServerList(); if (terminalServerList != null && terminalServerList.size() > 0) { // Check if the terminal server address is a valid numeric IP address for (String terminalServerAddress : terminalServerList) { if (IPAddress.isNumericAddress(terminalServerAddress) == false) throw new AlfrescoRuntimeException( "Invalid terminal server address, must be n.n.n.n format"); } // Set the terminal server address cifsConfig.setTerminalServerList(terminalServerList); } // Get the load balancer address List<String> loadBalancerList = cifsConfigBean.getLoadBalancerList(); if (loadBalancerList != null && loadBalancerList.size() > 0) { // Check if the load balancer address is a valid numeric IP address for (String loadBalancerAddress : loadBalancerList) { if (IPAddress.isNumericAddress(loadBalancerAddress) == false) throw new AlfrescoRuntimeException("Invalid load balancer address, must be n.n.n.n format"); } // Set the terminal server address cifsConfig.setLoadBalancerList(loadBalancerList); } // Get the host configuration String hostName = cifsConfigBean.getServerName(); if (hostName == null || hostName.length() == 0) { throw new AlfrescoRuntimeException("CIFS Host name not specified or invalid"); } // Get the local server name String srvName = getLocalServerName(true); // Check if the host name contains the local name token int pos = hostName.indexOf(TokenLocalName); if (pos != -1) { // Rebuild the host name substituting the token with the local server name StringBuilder hostStr = new StringBuilder(); hostStr.append(hostName.substring(0, pos)); hostStr.append(srvName); pos += TokenLocalName.length(); if (pos < hostName.length()) { hostStr.append(hostName.substring(pos)); } hostName = hostStr.toString(); } // Make sure the CIFS server name does not match the local server name if (hostName.toUpperCase().equals(srvName.toUpperCase()) && getPlatformType() == Platform.Type.WINDOWS) { throw new AlfrescoRuntimeException("CIFS server name must be unique"); } // Check if the host name is longer than 15 characters. NetBIOS only allows a maximum of 16 characters in // the // server name with the last character reserved for the service type. if (hostName.length() > 15) { // Truncate the CIFS server name hostName = hostName.substring(0, 15); // Output a warning logger.warn("CIFS server name is longer than 15 characters, truncated to " + hostName); } // Set the CIFS server name cifsConfig.setServerName(hostName.toUpperCase()); setServerName(hostName.toUpperCase()); // Get the domain/workgroup name String domain = cifsConfigBean.getDomainName(); if (domain != null && domain.length() > 0) { // Set the domain/workgroup name cifsConfig.setDomainName(domain.toUpperCase()); } else { // Get the local domain/workgroup name String localDomain = getLocalDomainName(); if (localDomain == null && (getPlatformType() != Platform.Type.WINDOWS || isNativeCodeDisabled())) { // Use a default domain/workgroup name localDomain = "WORKGROUP"; // Output a warning logger.warn("CIFS, Unable to get local domain/workgroup name, using default of " + localDomain + ". This may be due to firewall settings or incorrect <broadcast> setting)"); } // Set the local domain/workgroup that the CIFS server belongs to cifsConfig.setDomainName(localDomain); } // Check for a server comment String comment = cifsConfigBean.getServerComment(); if (comment != null && comment.length() > 0) { cifsConfig.setComment(comment); } // Set the maximum virtual circuits per session if (cifsConfigBean.getMaximumVirtualCircuits() < VirtualCircuitList.MinCircuits || cifsConfigBean.getMaximumVirtualCircuits() > VirtualCircuitList.MaxCircuits) throw new AlfrescoRuntimeException("Invalid virtual circuits value, valid range is " + VirtualCircuitList.MinCircuits + " - " + VirtualCircuitList.MaxCircuits); else cifsConfig.setMaximumVirtualCircuits(cifsConfigBean.getMaximumVirtualCircuits()); // Check for a bind address // Check if the network adapter name has been specified String bindToAdapter = cifsConfigBean.getBindToAdapter(); String bindTo; if (bindToAdapter != null && bindToAdapter.length() > 0) { // Get the IP address for the adapter InetAddress bindAddr = parseAdapterName(bindToAdapter); // Set the bind address for the server cifsConfig.setSMBBindAddress(bindAddr); } else if ((bindTo = cifsConfigBean.getBindToAddress()) != null && bindTo.length() > 0 && !bindTo.equals(BIND_TO_IGNORE)) { // Validate the bind address try { // Check the bind address InetAddress bindAddr = InetAddress.getByName(bindTo); // Set the bind address for the server cifsConfig.setSMBBindAddress(bindAddr); } catch (UnknownHostException ex) { throw new AlfrescoRuntimeException("CIFS Unable to bind to address :" + bindTo, ex); } } // Get the authenticator if (authenticator != null) { cifsConfig.setAuthenticator(authenticator); } else { throw new AlfrescoRuntimeException("CIFS authenticator not specified"); } // Check if the host announcer has been disabled if (!cifsConfigBean.getHostAccouncerEnabled()) { // Switch off the host announcer cifsConfig.setHostAnnouncer(false); // Log that host announcements are not enabled logger.info("CIFS Host announcements not enabled"); } else { // Check for an announcement interval Integer interval = cifsConfigBean.getHostAccounceInterval(); if (interval != null) { cifsConfig.setHostAnnounceInterval(interval); } // Check if the domain name has been set, this is required if the // host announcer is enabled if (cifsConfig.getDomainName() == null) { throw new AlfrescoRuntimeException( "CIFS Domain name must be specified if host announcement is enabled"); } // Enable host announcement cifsConfig.setHostAnnouncer(true); } // Check if NetBIOS SMB is enabled NetBIOSSMBConfigBean netBIOSSMBConfigBean = cifsConfigBean.getNetBIOSSMB(); if (netBIOSSMBConfigBean != null) { // Check if NetBIOS over TCP/IP is enabled for the current platform String platformsStr = netBIOSSMBConfigBean.getPlatforms(); boolean platformOK = false; if (platformsStr != null && platformsStr.length() > 0) { // Parse the list of platforms that NetBIOS over TCP/IP is to be enabled for and // check if the current platform is included EnumSet<Platform.Type> enabledPlatforms = parsePlatformString(platformsStr); if (enabledPlatforms.contains(getPlatformType())) platformOK = true; } else { // No restriction on platforms platformOK = true; } // Enable the NetBIOS SMB support, if enabled for this platform cifsConfig.setNetBIOSSMB(platformOK); // Parse/check NetBIOS settings, if enabled if (cifsConfig.hasNetBIOSSMB()) { // Check if the broadcast mask has been specified if (cifsConfig.getBroadcastMask() == null) { throw new AlfrescoRuntimeException("CIFS Network broadcast mask not specified"); } // Check for a bind address String bindto = netBIOSSMBConfigBean.getBindTo(); if (bindto != null && bindto.length() > 0 && !bindto.equals(BIND_TO_IGNORE)) { // Validate the bind address try { // Check the bind address InetAddress bindAddr = InetAddress.getByName(bindto); // Set the bind address for the NetBIOS name server cifsConfig.setNetBIOSBindAddress(bindAddr); } catch (UnknownHostException ex) { throw new AlfrescoRuntimeException("CIFS Invalid NetBIOS bind address:" + bindto, ex); } } else if (cifsConfig.hasSMBBindAddress()) { // Use the SMB bind address for the NetBIOS name server cifsConfig.setNetBIOSBindAddress(cifsConfig.getSMBBindAddress()); } else { // Get a list of all the local addresses InetAddress[] addrs = null; try { // Get the local server IP address list addrs = InetAddress.getAllByName(InetAddress.getLocalHost().getHostName()); } catch (UnknownHostException ex) { logger.error("CIFS Failed to get local address list", ex); } // Check the address list for one or more valid local addresses filtering out the loopback // address int addrCnt = 0; if (addrs != null) { for (int i = 0; i < addrs.length; i++) { // Check for a valid address, filter out '127.0.0.1' and '0.0.0.0' addresses if (addrs[i].getHostAddress().equals("127.0.0.1") == false && addrs[i].getHostAddress().equals("0.0.0.0") == false) addrCnt++; } } // Check if any addresses were found if (addrCnt == 0) { // Enumerate the network adapter list Enumeration<NetworkInterface> niEnum = null; try { niEnum = NetworkInterface.getNetworkInterfaces(); } catch (SocketException ex) { } if (niEnum != null) { while (niEnum.hasMoreElements()) { // Get the current network interface NetworkInterface ni = niEnum.nextElement(); // Enumerate the addresses for the network adapter Enumeration<InetAddress> niAddrs = ni.getInetAddresses(); if (niAddrs != null) { // Check for any valid addresses while (niAddrs.hasMoreElements()) { InetAddress curAddr = niAddrs.nextElement(); if (curAddr.getHostAddress().equals("127.0.0.1") == false && curAddr.getHostAddress().equals("0.0.0.0") == false) addrCnt++; } } } // DEBUG if (addrCnt > 0 && logger.isDebugEnabled()) logger.debug("Found valid IP address from interface list"); } // Check if we found any valid network addresses if (addrCnt == 0) { // Log the available IP addresses if (logger.isDebugEnabled()) { logger.debug("Local address list dump :-"); if (addrs != null) { for (int i = 0; i < addrs.length; i++) logger.debug(" Address: " + addrs[i]); } else { logger.debug(" No addresses"); } } // Throw an exception to stop the CIFS/NetBIOS name server from starting throw new AlfrescoRuntimeException( "Failed to get IP address(es) for the local server, check hosts file and/or DNS setup"); } } } // Check if the session port has been specified Integer portNum = netBIOSSMBConfigBean.getSessionPort(); if (portNum != null) { cifsConfig.setSessionPort(portNum); if (cifsConfig.getSessionPort() <= 0 || cifsConfig.getSessionPort() >= 65535) throw new AlfrescoRuntimeException("NetBIOS session port out of valid range"); } // Check if the name port has been specified portNum = netBIOSSMBConfigBean.getNamePort(); if (portNum != null) { cifsConfig.setNameServerPort(portNum); if (cifsConfig.getNameServerPort() <= 0 || cifsConfig.getNameServerPort() >= 65535) throw new AlfrescoRuntimeException("NetBIOS name port out of valid range"); } // Check if the datagram port has been specified portNum = netBIOSSMBConfigBean.getDatagramPort(); if (portNum != null) { cifsConfig.setDatagramPort(portNum); if (cifsConfig.getDatagramPort() <= 0 || cifsConfig.getDatagramPort() >= 65535) throw new AlfrescoRuntimeException("NetBIOS datagram port out of valid range"); } // Check for a bind address String attr = netBIOSSMBConfigBean.getBindTo(); if (attr != null && attr.length() > 0 && !attr.equals(BIND_TO_IGNORE)) { // Validate the bind address try { // Check the bind address InetAddress bindAddr = InetAddress.getByName(attr); // Set the bind address for the NetBIOS name server cifsConfig.setNetBIOSBindAddress(bindAddr); } catch (UnknownHostException ex) { throw new InvalidConfigurationException(ex.toString()); } } // Check for a bind address using the adapter name else if ((attr = netBIOSSMBConfigBean.getAdapter()) != null && attr.length() > 0) { // Get the bind address via the network adapter name InetAddress bindAddr = parseAdapterName(attr); cifsConfig.setNetBIOSBindAddress(bindAddr); } else if (cifsConfig.hasSMBBindAddress()) { // Use the SMB bind address for the NetBIOS name server cifsConfig.setNetBIOSBindAddress(cifsConfig.getSMBBindAddress()); } } } else { // Disable NetBIOS SMB support cifsConfig.setNetBIOSSMB(false); } // Check if TCP/IP SMB is enabled TcpipSMBConfigBean tcpipSMBConfigBean = cifsConfigBean.getTcpipSMB(); if (tcpipSMBConfigBean != null) { // Check if native SMB is enabled for the current platform String platformsStr = tcpipSMBConfigBean.getPlatforms(); boolean platformOK = false; if (platformsStr != null) { // Parse the list of platforms that native SMB is to be enabled for and // check if the current platform is included EnumSet<Platform.Type> enabledPlatforms = parsePlatformString(platformsStr); if (enabledPlatforms.contains(getPlatformType())) platformOK = true; } else { // No restriction on platforms platformOK = true; } // Enable the TCP/IP SMB support, if enabled for this platform cifsConfig.setTcpipSMB(platformOK); // Check if the port has been specified Integer portNum = tcpipSMBConfigBean.getPort(); if (portNum != null) { cifsConfig.setTcpipSMBPort(portNum); if (cifsConfig.getTcpipSMBPort() <= 0 || cifsConfig.getTcpipSMBPort() >= 65535) throw new AlfrescoRuntimeException("TCP/IP SMB port out of valid range"); } // Check if IPv6 support should be enabled if (tcpipSMBConfigBean.getIpv6Enabled()) { try { // Use the IPv6 bind all address cifsConfig.setSMBBindAddress(InetAddress.getByName("::")); // DEBUG if (logger.isInfoEnabled()) { logger.info("Enabled CIFS IPv6 bind address for native SMB"); } } catch (UnknownHostException ex) { throw new AlfrescoRuntimeException( "CIFS Failed to enable IPv6 bind address, " + ex.getMessage()); } } } else { // Disable TCP/IP SMB support cifsConfig.setTcpipSMB(false); } // Check if Win32 NetBIOS is enabled Win32NetBIOSConfigBean win32NetBIOSConfigBean = cifsConfigBean.getWin32NetBIOS(); if (win32NetBIOSConfigBean != null) { // Check if the Win32 NetBIOS server name has been specified String win32Name = win32NetBIOSConfigBean.getName(); if (win32Name != null && win32Name.length() > 0) { // Validate the name if (win32Name.length() > 16) throw new AlfrescoRuntimeException("Invalid Win32 NetBIOS name, " + win32Name); // Set the Win32 NetBIOS file server name cifsConfig.setWin32NetBIOSName(win32Name); } // Check if the Win32 NetBIOS LANA has been specified String lanaStr = win32NetBIOSConfigBean.getLana(); if (lanaStr != null && lanaStr.length() > 0) { // Check if the LANA has been specified as an IP address or adapter name int lana = -1; if (IPAddress.isNumericAddress(lanaStr)) { // Convert the IP address to a LANA id lana = Win32NetBIOS.getLANAForIPAddress(lanaStr); if (lana == -1) throw new AlfrescoRuntimeException( "Failed to convert IP address " + lanaStr + " to a LANA"); } else if (lanaStr.length() > 1 && Character.isLetter(lanaStr.charAt(0))) { // Convert the network adapter to a LANA id lana = Win32NetBIOS.getLANAForAdapterName(lanaStr); if (lana == -1) throw new AlfrescoRuntimeException( "Failed to convert network adapter " + lanaStr + " to a LANA"); } else { try { lana = Integer.parseInt(lanaStr); } catch (NumberFormatException ex) { throw new AlfrescoRuntimeException("Invalid win32 NetBIOS LANA specified"); } } // LANA should be in the range 0-255 if (lana < 0 || lana > 255) throw new AlfrescoRuntimeException("Invalid Win32 NetBIOS LANA number, " + lana); // Set the LANA number cifsConfig.setWin32LANA(lana); } // Check if the native NetBIOS interface has been specified, either 'winsock' or 'netbios' String nativeAPI = win32NetBIOSConfigBean.getApi(); if (nativeAPI != null && nativeAPI.length() > 0) { // Validate the API type boolean useWinsock = true; if (nativeAPI.equalsIgnoreCase("netbios")) useWinsock = false; else if (nativeAPI.equalsIgnoreCase("winsock") == false) throw new AlfrescoRuntimeException( "Invalid NetBIOS API type, spefify 'winsock' or 'netbios'"); // Set the NetBIOS API to use cifsConfig.setWin32WinsockNetBIOS(useWinsock); } // Force the older NetBIOS API code to be used on 64Bit Windows if (cifsConfig.useWinsockNetBIOS() == true && X64.isWindows64()) { // Debug if (logger.isDebugEnabled()) logger.debug("Using older Netbios() API code"); // Use the older NetBIOS API code cifsConfig.setWin32WinsockNetBIOS(false); } // Check if the current operating system is supported by the Win32 // NetBIOS handler String osName = System.getProperty("os.name"); if (osName.startsWith("Windows") && (osName.endsWith("95") == false && osName.endsWith("98") == false && osName.endsWith("ME") == false) && isNativeCodeDisabled() == false) { // Call the Win32NetBIOS native code to make sure it is initialized if (Win32NetBIOS.LanaEnumerate() != null) { // Enable Win32 NetBIOS cifsConfig.setWin32NetBIOS(true); } else { logger.warn("No NetBIOS LANAs available"); } } else { // Win32 NetBIOS not supported on the current operating system cifsConfig.setWin32NetBIOS(false); } } else { // Disable Win32 NetBIOS cifsConfig.setWin32NetBIOS(false); } // Check if the Win32 host announcer has been disabled if (!cifsConfigBean.getWin32HostAnnouncerEnabled()) { // Switch off the Win32 host announcer cifsConfig.setWin32HostAnnouncer(false); // Log that host announcements are not enabled logger.info("Win32 host announcements not enabled"); } else { // Check for an announcement interval Integer interval = cifsConfigBean.getWin32HostAnnounceInterval(); if (interval != null) { cifsConfig.setWin32HostAnnounceInterval(interval); } // Check if the domain name has been set, this is required if the // host announcer is enabled if (cifsConfig.getDomainName() == null) throw new AlfrescoRuntimeException( "Domain name must be specified if host announcement is enabled"); // Enable Win32 NetBIOS host announcement cifsConfig.setWin32HostAnnouncer(true); } // Check if NetBIOS and/or TCP/IP SMB have been enabled if (cifsConfig.hasNetBIOSSMB() == false && cifsConfig.hasTcpipSMB() == false && cifsConfig.hasWin32NetBIOS() == false) throw new AlfrescoRuntimeException("NetBIOS SMB, TCP/IP SMB or Win32 NetBIOS must be enabled"); // Check if WINS servers are configured WINSConfigBean winsConfigBean = cifsConfigBean.getWINSConfig(); if (winsConfigBean != null && !winsConfigBean.isAutoDetectEnabled()) { // Get the primary WINS server String priWins = winsConfigBean.getPrimary(); if (priWins == null || priWins.length() == 0) throw new AlfrescoRuntimeException("No primary WINS server configured"); // Validate the WINS server address InetAddress primaryWINS = null; try { primaryWINS = InetAddress.getByName(priWins); } catch (UnknownHostException ex) { throw new AlfrescoRuntimeException("Invalid primary WINS server address, " + priWins); } // Check if a secondary WINS server has been specified String secWins = winsConfigBean.getSecondary(); InetAddress secondaryWINS = null; if (secWins != null && secWins.length() > 0) { // Validate the secondary WINS server address try { secondaryWINS = InetAddress.getByName(secWins); } catch (UnknownHostException ex) { throw new AlfrescoRuntimeException("Invalid secondary WINS server address, " + secWins); } } // Set the WINS server address(es) cifsConfig.setPrimaryWINSServer(primaryWINS); if (secondaryWINS != null) cifsConfig.setSecondaryWINSServer(secondaryWINS); // Pass the setting to the NetBIOS session class NetBIOSSession.setDefaultWINSServer(primaryWINS); } // Check if WINS is configured, if we are running on Windows and socket based NetBIOS is enabled else if (cifsConfig.hasNetBIOSSMB() && getPlatformType() == Platform.Type.WINDOWS && !isNativeCodeDisabled()) { // Get the WINS server list String winsServers = Win32NetBIOS.getWINSServerList(); if (winsServers != null) { // Use the first WINS server address for now StringTokenizer tokens = new StringTokenizer(winsServers, ","); String addr = tokens.nextToken(); try { // Convert to a network address and check if the WINS server is accessible InetAddress winsAddr = InetAddress.getByName(addr); Socket winsSocket = new Socket(); InetSocketAddress sockAddr = new InetSocketAddress(winsAddr, RFCNetBIOSProtocol.NAME_PORT); winsSocket.connect(sockAddr, 3000); winsSocket.close(); // Set the primary WINS server address cifsConfig.setPrimaryWINSServer(winsAddr); // Debug if (logger.isDebugEnabled()) logger.debug("Configuring to use WINS server " + addr); } catch (UnknownHostException ex) { throw new AlfrescoRuntimeException("Invalid auto WINS server address, " + addr); } catch (IOException ex) { if (logger.isDebugEnabled()) logger.debug("Failed to connect to auto WINS server " + addr); } } } // Check for session debug flags String flags = cifsConfigBean.getSessionDebugFlags(); int sessDbg = 0; if (flags != null && flags.length() > 0) { // Parse the flags flags = flags.toUpperCase(); StringTokenizer token = new StringTokenizer(flags, ","); while (token.hasMoreTokens()) { // Get the current debug flag token String dbg = token.nextToken().trim(); // Find the debug flag name int idx = 0; while (idx < m_sessDbgStr.length && m_sessDbgStr[idx].equalsIgnoreCase(dbg) == false) idx++; if (idx > m_sessDbgStr.length) throw new AlfrescoRuntimeException("Invalid session debug flag, " + dbg); // Set the debug flag sessDbg += 1 << idx; } } // Set the session debug flags cifsConfig.setSessionDebugFlags(sessDbg); // Check if NIO based socket code should be disabled if (cifsConfigBean.getDisableNIO()) { // Disable NIO based code cifsConfig.setDisableNIOCode(true); // DEBUG if (logger.isDebugEnabled()) logger.debug("NIO based code disabled for CIFS server"); } // Check if a session timeout is configured Integer tmo = cifsConfigBean.getSessionTimeout(); if (tmo != null) { // Validate the session timeout value cifsConfigBean.validateSessionTimeout(tmo); // Convert the session timeout to milliseconds cifsConfig.setSocketTimeout(tmo * 1000); } } catch (InvalidConfigurationException ex) { throw new AlfrescoRuntimeException(ex.getMessage()); } } /** * Process the FTP server configuration */ protected void processFTPServerConfig() { // If the configuration section is not valid then FTP is disabled if (ftpConfigBean == null) { removeConfigSection(FTPConfigSection.SectionName); return; } // Check if the server has been disabled if (!ftpConfigBean.getServerEnabled()) { removeConfigSection(FTPConfigSection.SectionName); return; } // Create the FTP configuration section FTPConfigSection ftpConfig = new FTPConfigSection(this); try { // Check for a bind address String bindText = ftpConfigBean.getBindTo(); if (bindText != null && bindText.length() > 0 && !bindText.equals(BIND_TO_IGNORE)) { // Validate the bind address try { // Check the bind address InetAddress bindAddr = InetAddress.getByName(bindText); // Set the bind address for the FTP server ftpConfig.setFTPBindAddress(bindAddr); } catch (UnknownHostException ex) { throw new AlfrescoRuntimeException("Unable to find FTP bindto address, " + bindText, ex); } } // Check for an FTP server port Integer port = ftpConfigBean.getPort(); if (port != null) { ftpConfig.setFTPPort(port); if (ftpConfig.getFTPPort() <= 0 || ftpConfig.getFTPPort() >= 65535) throw new AlfrescoRuntimeException("FTP server port out of valid range"); } else { // Use the default FTP port ftpConfig.setFTPPort(DefaultFTPServerPort); } // Check for an FTP server timeout for connection to client Integer sessionTimeout = ftpConfigBean.getSessionTimeout(); if (sessionTimeout != null) { ftpConfig.setFTPSrvSessionTimeout(sessionTimeout); if (ftpConfig.getFTPSrvSessionTimeout() < 0) throw new AlfrescoRuntimeException( "FTP server session timeout must have positive value or zero"); } else { // Use the default timeout ftpConfig.setFTPSrvSessionTimeout(DefaultFTPSrvSessionTimeout); } // Check if anonymous login is allowed if (ftpConfigBean.getAllowAnonymous()) { // Enable anonymous login to the FTP server ftpConfig.setAllowAnonymousFTP(true); // Check if an anonymous account has been specified String anonAcc = ftpConfigBean.getAnonymousAccount(); if (anonAcc != null && anonAcc.length() > 0) { // Set the anonymous account name ftpConfig.setAnonymousFTPAccount(anonAcc); // Check if the anonymous account name is valid if (ftpConfig.getAnonymousFTPAccount() == null || ftpConfig.getAnonymousFTPAccount().length() == 0) { throw new AlfrescoRuntimeException("Anonymous FTP account invalid"); } } else { // Use the default anonymous account name ftpConfig.setAnonymousFTPAccount(DefaultFTPAnonymousAccount); } } else { // Disable anonymous logins ftpConfig.setAllowAnonymousFTP(false); } // Check if a root path has been specified String rootPath = ftpConfigBean.getRootDirectory(); if (rootPath != null && rootPath.length() > 0) { try { // Parse the path new FTPPath(rootPath); // Set the root path ftpConfig.setFTPRootPath(rootPath); } catch (InvalidPathException ex) { throw new AlfrescoRuntimeException("Invalid FTP root directory, " + rootPath); } } // Check for FTP debug flags String flags = ftpConfigBean.getDebugFlags(); int ftpDbg = 0; if (flags != null) { // Parse the flags flags = flags.toUpperCase(); StringTokenizer token = new StringTokenizer(flags, ","); while (token.hasMoreTokens()) { // Get the current debug flag token String dbg = token.nextToken().trim(); // Find the debug flag name int idx = 0; while (idx < m_ftpDebugStr.length && m_ftpDebugStr[idx].equalsIgnoreCase(dbg) == false) idx++; if (idx >= m_ftpDebugStr.length) throw new AlfrescoRuntimeException("Invalid FTP debug flag, " + dbg); // Set the debug flag ftpDbg += 1 << idx; } // Set the FTP debug flags ftpConfig.setFTPDebug(ftpDbg); } // Check if a character set has been specified String charSet = ftpConfigBean.getCharSet(); if (charSet != null && charSet.length() > 0) { try { // Validate the character set name Charset.forName(charSet); // Set the FTP character set ftpConfig.setFTPCharacterSet(charSet); } catch (IllegalCharsetNameException ex) { throw new AlfrescoRuntimeException("FTP Illegal character set name, " + charSet); } catch (UnsupportedCharsetException ex) { throw new AlfrescoRuntimeException("FTP Unsupported character set name, " + charSet); } } // Check if an authenticator has been specified FTPAuthenticator auth = ftpConfigBean.getAuthenticator(); if (auth != null) { // Initialize and set the authenticator class ftpConfig.setAuthenticator(auth); } else throw new AlfrescoRuntimeException("FTP authenticator not specified"); // Check if a data port range has been specified if (ftpConfigBean.getDataPortFrom() != 0 && ftpConfigBean.getDataPortTo() != 0) { // Range check the data port values int rangeFrom = ftpConfigBean.getDataPortFrom(); int rangeTo = ftpConfigBean.getDataPortTo(); if (rangeFrom != 0 && rangeTo != 0) { // Validate the FTP data port range if (rangeFrom < 1024 || rangeFrom > 65535) throw new InvalidConfigurationException( "Invalid FTP data port range from value, " + rangeFrom); if (rangeTo < 1024 || rangeTo > 65535) throw new InvalidConfigurationException("Invalid FTP data port range to value, " + rangeTo); if (rangeFrom >= rangeTo) throw new InvalidConfigurationException( "Invalid FTP data port range, " + rangeFrom + "-" + rangeTo); // Set the FTP data port range ftpConfig.setFTPDataPortLow(rangeFrom); ftpConfig.setFTPDataPortHigh(rangeTo); // Log the data port range logger.info("FTP server data ports restricted to range " + rangeFrom + ":" + rangeTo); } } // FTPS parameter parsing // // Check if a key store path has been specified if (ftpConfigBean.getKeyStorePath() != null && ftpConfigBean.getKeyStorePath().length() > 0) { // Get the path to the key store, check that the file exists String keyStorePath = ftpConfigBean.getKeyStorePath(); File keyStoreFile = new File(keyStorePath); if (keyStoreFile.exists() == false) throw new InvalidConfigurationException("FTPS key store file does not exist, " + keyStorePath); else if (keyStoreFile.isDirectory()) throw new InvalidConfigurationException("FTPS key store path is a directory, " + keyStorePath); // Set the key store path ftpConfig.setKeyStorePath(keyStorePath); // Check if the key store type has been specified if (ftpConfigBean.getKeyStoreType() != null && ftpConfigBean.getKeyStoreType().length() > 0) { // Get the key store type, and validate String keyStoreType = ftpConfigBean.getKeyStoreType(); if (keyStoreType == null || keyStoreType.length() == 0) throw new InvalidConfigurationException("FTPS key store type is invalid"); try { KeyStore.getInstance(keyStoreType); } catch (KeyStoreException ex) { throw new InvalidConfigurationException("FTPS key store type is invalid, " + keyStoreType, ex); } // Set the key store type ftpConfig.setKeyStoreType(keyStoreType); } // Check if the key store passphrase has been specified if (ftpConfigBean.getKeyStorePassphrase() != null && ftpConfigBean.getKeyStorePassphrase().length() > 0) { // Set the key store passphrase ftpConfig.setKeyStorePassphrase(ftpConfigBean.getKeyStorePassphrase()); } } // Check if the trust store path has been specified if (ftpConfigBean.getTrustStorePath() != null && ftpConfigBean.getTrustStorePath().length() > 0) { // Get the path to the trust store, check that the file exists String trustStorePath = ftpConfigBean.getTrustStorePath(); File trustStoreFile = new File(trustStorePath); if (trustStoreFile.exists() == false) throw new InvalidConfigurationException( "FTPS trust store file does not exist, " + trustStorePath); else if (trustStoreFile.isDirectory()) throw new InvalidConfigurationException( "FTPS trust store path is a directory, " + trustStorePath); // Set the trust store path ftpConfig.setTrustStorePath(trustStorePath); // Check if the trust store type has been specified if (ftpConfigBean.getTrustStoreType() != null && ftpConfigBean.getTrustStoreType().length() > 0) { // Get the trust store type, and validate String trustStoreType = ftpConfigBean.getTrustStoreType(); if (trustStoreType == null || trustStoreType.length() == 0) throw new InvalidConfigurationException("FTPS trust store type is invalid"); try { KeyStore.getInstance(trustStoreType); } catch (KeyStoreException ex) { throw new InvalidConfigurationException( "FTPS trust store type is invalid, " + trustStoreType, ex); } // Set the trust store type ftpConfig.setTrustStoreType(trustStoreType); } // Check if the trust store passphrase has been specified if (ftpConfigBean.getTrustStorePassphrase() != null && ftpConfigBean.getTrustStorePassphrase().length() > 0) { // Set the trust store passphrase ftpConfig.setTrustStorePassphrase(ftpConfigBean.getTrustStorePassphrase()); } } // Check if only secure sessions should be allowed to logon if (ftpConfigBean.hasRequireSecureSession()) { // Only allow secure sessions to logon to the FTP server ftpConfig.setRequireSecureSession(true); } // Check that all the required FTPS parameters have been set // MNT-7301 FTPS server requires unnecessarly to have a trustStore while a keyStore should be sufficient if (ftpConfig.getKeyStorePath() != null) { // Make sure all parameters are set if (ftpConfig.getKeyStorePath() == null) throw new InvalidConfigurationException("FTPS configuration requires keyStore to be set"); } // Check if SSLEngine debug output should be enabled if (ftpConfigBean.hasSslEngineDebug()) { // Enable SSLEngine debug output System.setProperty("javax.net.debug", "ssl,handshake"); } } catch (InvalidConfigurationException ex) { throw new AlfrescoRuntimeException(ex.getMessage()); } } /** * Process the NFS server configuration */ protected void processNFSServerConfig() { // If the configuration section is not valid then NFS is disabled if (nfsConfigBean == null) { removeConfigSection(NFSConfigSection.SectionName); return; } // Check if the server has been disabled if (!nfsConfigBean.getServerEnabled()) { removeConfigSection(NFSConfigSection.SectionName); return; } // Create the NFS configuration section NFSConfigSection nfsConfig = new NFSConfigSection(this); try { // Check if the port mapper is enabled if (nfsConfigBean.getPortMapperEnabled()) nfsConfig.setNFSPortMapper(true); // Check for the thread pool size Integer poolSize = nfsConfigBean.getThreadPool(); if (poolSize != null) { // Range check the pool size value if (poolSize < 4) { throw new AlfrescoRuntimeException("NFS thread pool size is below minimum of 4"); } // Set the thread pool size nfsConfig.setNFSThreadPoolSize(poolSize); } // NFS packet pool size Integer pktPoolSize = nfsConfigBean.getPacketPool(); if (pktPoolSize != null) { // Range check the pool size value if (pktPoolSize < 10) throw new AlfrescoRuntimeException("NFS packet pool size is below minimum of 10"); if (pktPoolSize < nfsConfig.getNFSThreadPoolSize() + 1) throw new AlfrescoRuntimeException( "NFS packet pool must be at least thread pool size plus one"); // Set the packet pool size nfsConfig.setNFSPacketPoolSize(pktPoolSize); } // Check for a port mapper server port Integer portMapperPort = nfsConfigBean.getPortMapperPort(); if (portMapperPort != null) { nfsConfig.setPortMapperPort(portMapperPort); if (nfsConfig.getPortMapperPort() == -1) { logger.info("NFS portmapper registration disabled"); } else { if (nfsConfig.getPortMapperPort() <= 0 || nfsConfig.getPortMapperPort() >= 65535) { throw new AlfrescoRuntimeException("NFS Port mapper server port out of valid range"); } } } // Check for a mount server port Integer mountServerPort = nfsConfigBean.getMountServerPort(); if (mountServerPort != null) { nfsConfig.setMountServerPort(mountServerPort); if (nfsConfig.getMountServerPort() < 0 || nfsConfig.getMountServerPort() >= 65535) { throw new AlfrescoRuntimeException("NFS Mount server port out of valid range"); } } // Check for an NFS server port Integer nfsServerPort = nfsConfigBean.getNfsServerPort(); if (nfsServerPort != null) { nfsConfig.setNFSServerPort(nfsServerPort); if (nfsConfig.getNFSServerPort() < 0 || nfsConfig.getNFSServerPort() >= 65535) { throw new AlfrescoRuntimeException("NFS server port out of valid range"); } } // Check for an RPC registration port Integer rpcRegisterPort = nfsConfigBean.getRpcRegisterPort(); if (rpcRegisterPort != null) { nfsConfig.setRPCRegistrationPort(rpcRegisterPort); if (nfsConfig.getRPCRegistrationPort() < 0 || nfsConfig.getRPCRegistrationPort() >= 65535) { throw new AlfrescoRuntimeException("RPC registrtion port out of valid range"); } } // Check for NFS debug flags String flags = nfsConfigBean.getDebugFlags(); int nfsDbg = 0; if (flags != null && flags.length() > 0) { // Parse the flags flags = flags.toUpperCase(); StringTokenizer token = new StringTokenizer(flags, ","); while (token.hasMoreTokens()) { // Get the current debug flag token String dbg = token.nextToken().trim(); // Find the debug flag name int idx = 0; while (idx < m_nfsDebugStr.length && m_nfsDebugStr[idx].equalsIgnoreCase(dbg) == false) idx++; if (idx >= m_nfsDebugStr.length) throw new AlfrescoRuntimeException("Invalid NFS debug flag, " + dbg); // Set the debug flag nfsDbg += 1 << idx; } // Set the NFS debug flags nfsConfig.setNFSDebug(nfsDbg); } // Check if mount server debug output is enabled if (nfsConfigBean.getMountServerDebug()) nfsConfig.setMountServerDebug(true); // Check if portmapper debug output is enabled if (nfsConfigBean.getPortMapperDebug()) nfsConfig.setPortMapperDebug(true); // Create the RPC authenticator RpcAuthenticator rpcAuthenticator = nfsConfigBean.getRpcAuthenticator(); if (rpcAuthenticator != null) { nfsConfig.setRpcAuthenticator(rpcAuthenticator); } else { throw new AlfrescoRuntimeException( "RPC authenticator configuration missing, require user mappings"); } } catch (InvalidConfigurationException ex) { throw new AlfrescoRuntimeException(ex.getMessage()); } } /** * Process the filesystems configuration */ protected void processFilesystemsConfig() { // Create the filesystems configuration section FilesystemsConfigSection fsysConfig = new FilesystemsConfigSection(this); // Access the security configuration section SecurityConfigSection secConfig = (SecurityConfigSection) getConfigSection( SecurityConfigSection.SectionName); // Process the filesystems list if (this.filesystemContexts != null) { // Add the filesystems for (DeviceContext filesystem : this.filesystemContexts) { // Get the current filesystem configuration try { // Check the filesystem type and use the appropriate driver DiskSharedDevice filesys = null; // Create a new filesystem driver instance and register a context for // the new filesystem ExtendedDiskInterface filesysDriver = getRepoDiskInterface(); ContentContext filesysContext = (ContentContext) filesystem; if (clusterConfigBean != null && clusterConfigBean.getClusterEnabled()) { if (logger.isDebugEnabled()) { logger.debug("start hazelcast cache : " + clusterConfigBean.getClusterName() + ", shareName: " + filesysContext.getShareName()); } GenericConfigElement hazelConfig = createClusterConfig( "cifs.filesys." + filesysContext.getShareName()); HazelCastClusterFileStateCache hazel = new HazelCastClusterFileStateCache(); hazel.initializeCache(hazelConfig, this); filesysContext.setStateCache(hazel); } else { // Create state cache here and inject StandaloneFileStateCache standaloneCache = new StandaloneFileStateCache(); standaloneCache.initializeCache(new GenericConfigElement(""), this); filesysContext.setStateCache(standaloneCache); } if (filesysContext.hasStateCache()) { // Register the state cache with the reaper thread // has many side effects including initialisation of the cache fsysConfig.addFileStateCache(filesystem.getDeviceName(), filesysContext.getStateCache()); // Create the lock manager for the context. FileStateLockManager lockMgr = new FileStateLockManager(filesysContext.getStateCache()); filesysContext.setLockManager(lockMgr); filesysContext.setOpLockManager(lockMgr); } if ((!cifsConfigBean.getServerEnabled() && !ftpConfigBean.getServerEnabled()) && isContentDiskDriver2(filesysDriver)) { ((ContentContext) filesystem).setDisableNodeMonitor(true); } filesysDriver.registerContext(filesystem); // Check if an access control list has been specified AccessControlList acls = null; AccessControlListBean accessControls = filesysContext.getAccessControlList(); if (accessControls != null) { // Parse the access control list acls = accessControls.toAccessControlList(secConfig); } else if (secConfig.hasGlobalAccessControls()) { // Use the global access control list for this disk share acls = secConfig.getGlobalAccessControls(); } // Create the shared filesystem filesys = new DiskSharedDevice(filesystem.getDeviceName(), filesysDriver, filesysContext); filesys.setConfiguration(this); // Add any access controls to the share filesys.setAccessControlList(acls); // Check if change notifications should be enabled if (filesysContext.getDisableChangeNotifications() == false) filesysContext.enableChangeHandler(true); // Start the filesystem filesysContext.startFilesystem(filesys); // Add the new filesystem fsysConfig.addShare(filesys); } catch (DeviceContextException ex) { throw new AlfrescoRuntimeException("Error creating filesystem " + filesystem.getDeviceName(), ex); } catch (InvalidConfigurationException ex) { throw new AlfrescoRuntimeException(ex.getMessage(), ex); } } } else { // No filesystems defined logger.warn("No filesystems defined"); } // home folder share mapper could be declared in security config } /** * Returns true if either: the disk interface is a ContentDiskDriver2; or * the disk interface is a {@link BufferedContentDiskDriver} and its disk * interface is a ContentDiskDriver2 (wrapped by several other DiskInterface objects). * * @param diskInterface ExtendedDiskInterface * @return boolean */ private boolean isContentDiskDriver2(ExtendedDiskInterface diskInterface) { if (diskInterface instanceof ContentDiskDriver2) { return true; } if (diskInterface instanceof BufferedContentDiskDriver) { BufferedContentDiskDriver bufferedDriver = (BufferedContentDiskDriver) diskInterface; ExtendedDiskInterface underlyingDriver = bufferedDriver.getDiskInterface(); if (underlyingDriver instanceof LegacyFileStateDriver) { LegacyFileStateDriver legacyDriver = (LegacyFileStateDriver) underlyingDriver; underlyingDriver = legacyDriver.getDiskInterface(); if (underlyingDriver instanceof NonTransactionalRuleContentDiskDriver) { // This is the best we can do. The underlying driver of this driver (the // NonTransactionalRuleContentDiskDriver) is a dynamic proxy and we can't // say for sure if it is a ContentDiskDriver2. return true; } } } return false; } /** * Process the security configuration */ protected void processSecurityConfig() { // Create the security configuration section SecurityConfigSection secConfig = new SecurityConfigSection(this); try { // Check if global access controls have been specified AccessControlListBean accessControls = securityConfigBean.getGlobalAccessControl(); if (accessControls != null) { // Parse the access control list AccessControlList acls = accessControls.toAccessControlList(secConfig); if (acls != null) secConfig.setGlobalAccessControls(acls); } // Check if a JCE provider class has been specified String jceProvider = securityConfigBean.getJCEProvider(); if (jceProvider != null && jceProvider.length() > 0) { // Set the JCE provider secConfig.setJCEProvider(jceProvider); } else { // Use the default Bouncy Castle JCE provider secConfig.setJCEProvider("org.bouncycastle.jce.provider.BouncyCastleProvider"); } // Check if a share mapper has been specified ShareMapper shareMapper = securityConfigBean.getShareMapper(); if (shareMapper != null) { // Associate the share mapper secConfig.setShareMapper(shareMapper); } // Check if any domain mappings have been specified List<DomainMappingConfigBean> mappings = securityConfigBean.getDomainMappings(); if (mappings != null) { DomainMapping mapping = null; for (DomainMappingConfigBean domainMap : mappings) { // Get the domain name String name = domainMap.getName(); // Check if the domain is specified by subnet or range String subnetStr = domainMap.getSubnet(); String rangeFromStr; if (subnetStr != null && subnetStr.length() > 0) { String maskStr = domainMap.getMask(); // Parse the subnet and mask, to validate and convert to int values int subnet = IPAddress.parseNumericAddress(subnetStr); int mask = IPAddress.parseNumericAddress(maskStr); if (subnet == 0 || mask == 0) throw new AlfrescoRuntimeException("Invalid subnet/mask for domain mapping " + name); // Create the subnet domain mapping mapping = new SubnetDomainMapping(name, subnet, mask); } else if ((rangeFromStr = domainMap.getRangeFrom()) != null && rangeFromStr.length() > 0) { String rangeToStr = domainMap.getRangeTo(); // Parse the range from/to values and convert to int values int rangeFrom = IPAddress.parseNumericAddress(rangeFromStr); int rangeTo = IPAddress.parseNumericAddress(rangeToStr); if (rangeFrom == 0 || rangeTo == 0) throw new AlfrescoRuntimeException("Invalid address range domain mapping " + name); // Create the subnet domain mapping mapping = new RangeDomainMapping(name, rangeFrom, rangeTo); } else throw new AlfrescoRuntimeException("Invalid domain mapping specified"); // Add the domain mapping secConfig.addDomainMapping(mapping); } } } catch (InvalidConfigurationException ex) { throw new AlfrescoRuntimeException(ex.getMessage()); } } /** * Process the core server configuration * * @exception InvalidConfigurationException */ protected void processCoreServerConfig() throws InvalidConfigurationException { // Create the core server configuration section CoreServerConfigSection coreConfig = new CoreServerConfigSection(this); // Check if the CIFS server is not enabled, do not create the thread/memory pools if (cifsConfigBean == null || cifsConfigBean.getServerEnabled() == false) return; // Check if the server core element has been specified if (coreServerConfigBean == null) { // Configure a default memory pool coreConfig.setMemoryPool(DefaultMemoryPoolBufSizes, DefaultMemoryPoolInitAlloc, DefaultMemoryPoolMaxAlloc); // Configure a default thread pool size coreConfig.setThreadPool(DefaultThreadPoolInit, DefaultThreadPoolMax); threadPool = coreConfig.getThreadPool(); return; } // Check if the thread pool size has been specified Integer initSize = coreServerConfigBean.getThreadPoolInit(); if (initSize == null) { initSize = DefaultThreadPoolInit; } Integer maxSize = coreServerConfigBean.getThreadPoolMax(); if (maxSize == null) { maxSize = DefaultThreadPoolMax; } // Range check the thread pool size if (initSize < ThreadRequestPool.MinimumWorkerThreads) throw new InvalidConfigurationException("Thread pool size below minimum allowed size"); if (initSize > ThreadRequestPool.MaximumWorkerThreads) throw new InvalidConfigurationException("Thread pool size above maximum allowed size"); // Range check the maximum thread pool size if (maxSize < ThreadRequestPool.MinimumWorkerThreads) throw new InvalidConfigurationException("Thread pool maximum size below minimum allowed size"); if (maxSize > ThreadRequestPool.MaximumWorkerThreads) throw new InvalidConfigurationException("Thread pool maximum size above maximum allowed size"); if (maxSize < initSize) throw new InvalidConfigurationException("Initial size is larger than maxmimum size"); // Configure the thread pool coreConfig.setThreadPool(initSize, maxSize); threadPool = coreConfig.getThreadPool(); // Check if thread pool debug output is enabled if (coreServerConfigBean.getThreadPoolDebug()) coreConfig.getThreadPool().setDebug(true); // Check if the packet sizes/allocations have been specified List<MemoryPacketConfigBean> packetSizes = coreServerConfigBean.getMemoryPacketSizes(); if (packetSizes != null) { // Calculate the array size for the packet size/allocation arrays int elemCnt = packetSizes.size(); // Create the packet size, initial allocation and maximum allocation arrays int[] pktSizes = new int[elemCnt]; int[] initSizes = new int[elemCnt]; int[] maxSizes = new int[elemCnt]; int elemIdx = 0; // Process the packet size elements for (MemoryPacketConfigBean curChild : packetSizes) { // Get the packet size int pktSize = -1; Long pktSizeLong = curChild.getSize(); if (pktSizeLong == null) throw new InvalidConfigurationException("Memory pool packet size not specified"); // Parse the packet size try { pktSize = MemorySize.getByteValueInt(pktSizeLong.toString()); } catch (NumberFormatException ex) { throw new InvalidConfigurationException( "Memory pool packet size, invalid size value, " + pktSizeLong); } // Make sure the packet sizes have been specified in ascending order if (elemIdx > 0 && pktSizes[elemIdx - 1] >= pktSize) throw new InvalidConfigurationException( "Invalid packet size specified, less than/equal to previous packet size"); // Get the initial allocation for the current packet size Integer initAlloc = curChild.getInit(); if (initAlloc == null) throw new InvalidConfigurationException("Memory pool initial allocation not specified"); // Range check the initial allocation if (initAlloc < MemoryPoolMinimumAllocation) throw new InvalidConfigurationException( "Initial memory pool allocation below minimum of " + MemoryPoolMinimumAllocation); if (initAlloc > MemoryPoolMaximumAllocation) throw new InvalidConfigurationException( "Initial memory pool allocation above maximum of " + MemoryPoolMaximumAllocation); // Get the maximum allocation for the current packet size Integer maxAlloc = curChild.getMax(); if (maxAlloc == null) throw new InvalidConfigurationException("Memory pool maximum allocation not specified"); // Range check the maximum allocation if (maxAlloc < MemoryPoolMinimumAllocation) throw new InvalidConfigurationException( "Maximum memory pool allocation below minimum of " + MemoryPoolMinimumAllocation); if (initAlloc > MemoryPoolMaximumAllocation) throw new InvalidConfigurationException( "Maximum memory pool allocation above maximum of " + MemoryPoolMaximumAllocation); // Set the current packet size elements pktSizes[elemIdx] = pktSize; initSizes[elemIdx] = initAlloc; maxSizes[elemIdx] = maxAlloc; elemIdx++; } // Check if all elements were used in the packet size/allocation arrays if (elemIdx < pktSizes.length) { // Re-allocate the packet size/allocation arrays int[] newPktSizes = new int[elemIdx]; int[] newInitSizes = new int[elemIdx]; int[] newMaxSizes = new int[elemIdx]; // Copy the values to the shorter arrays System.arraycopy(pktSizes, 0, newPktSizes, 0, elemIdx); System.arraycopy(initSizes, 0, newInitSizes, 0, elemIdx); System.arraycopy(maxSizes, 0, newMaxSizes, 0, elemIdx); // Move the new arrays into place pktSizes = newPktSizes; initSizes = newInitSizes; maxSizes = newMaxSizes; } // Configure the memory pool coreConfig.setMemoryPool(pktSizes, initSizes, maxSizes); } else { // Configure a default memory pool coreConfig.setMemoryPool(DefaultMemoryPoolBufSizes, DefaultMemoryPoolInitAlloc, DefaultMemoryPoolMaxAlloc); } } /** * Initialise a runtime context - not configured through spring e.g MT. * * TODO - what about desktop actions etc? * * @param uniqueName String * @param diskCtx AlfrescoContext */ public void initialiseRuntimeContext(String uniqueName, AlfrescoContext diskCtx) { logger.debug("initialiseRuntimeContext" + diskCtx); if (diskCtx.getStateCache() == null) { // Set the state cache, use a hard coded standalone cache for now FilesystemsConfigSection filesysConfig = (FilesystemsConfigSection) this .getConfigSection(FilesystemsConfigSection.SectionName); if (filesysConfig != null) { try { if (clusterConfigBean != null && clusterConfigBean.getClusterEnabled()) { if (logger.isDebugEnabled()) { logger.debug("start hazelcast cache : " + clusterConfigBean.getClusterName() + ", uniqueName: " + uniqueName); } GenericConfigElement hazelConfig = createClusterConfig(uniqueName); HazelCastClusterFileStateCache hazel = new HazelCastClusterFileStateCache(); hazel.initializeCache(hazelConfig, this); diskCtx.setStateCache(hazel); } else { // Create a standalone state cache StandaloneFileStateCache standaloneCache = new StandaloneFileStateCache(); standaloneCache.initializeCache(new GenericConfigElement(""), this); filesysConfig.addFileStateCache(diskCtx.getDeviceName(), standaloneCache); diskCtx.setStateCache(standaloneCache); } // Register the state cache with the reaper thread // has many side effects including initialisation of the cache filesysConfig.addFileStateCache(diskCtx.getShareName(), diskCtx.getStateCache()); FileStateLockManager lockMgr = new FileStateLockManager(diskCtx.getStateCache()); diskCtx.setLockManager(lockMgr); diskCtx.setOpLockManager(lockMgr); } catch (InvalidConfigurationException ex) { throw new AlfrescoRuntimeException( "Failed to initialize standalone state cache for " + diskCtx.getDeviceName()); } } } } @Override protected void processClusterConfig() throws InvalidConfigurationException { // Done by org.alfresco.jlan.server.config.ServerConfiguration.closeConfiguration // /** // * Close the old hazelcast configuration // */ // ClusterConfigSection secConfig = (ClusterConfigSection) getConfigSection(ClusterConfigSection.SectionName); // { // if(secConfig != null) // { // secConfig.closeConfig(); // } // } if (clusterConfigBean == null || !clusterConfigBean.getClusterEnabled()) { removeConfigSection(ClusterConfigSection.SectionName); logger.info("Filesystem cluster cache not enabled"); return; } // Create a ClusterConfigSection and attach it to 'this'. ClusterConfigSection clusterConf = new ClusterConfigSection(this); } private GenericConfigElement createClusterConfig(String topicName) throws InvalidConfigurationException { GenericConfigElement config = new GenericConfigElement("hazelcastStateCache"); GenericConfigElement clusterNameCfg = new GenericConfigElement("clusterName"); clusterNameCfg.setValue(clusterConfigBean.getClusterName()); config.addChild(clusterNameCfg); GenericConfigElement topicNameCfg = new GenericConfigElement("clusterTopic"); if (topicName == null || topicName.isEmpty()) { topicName = "default"; } topicNameCfg.setValue(topicName); config.addChild(topicNameCfg); if (clusterConfigBean.getDebugFlags() != null) { GenericConfigElement debugCfg = new GenericConfigElement("cacheDebug"); debugCfg.addAttribute("flags", clusterConfigBean.getDebugFlags()); config.addChild(debugCfg); } if (clusterConfigBean.getNearCacheTimeout() > 0) { GenericConfigElement nearCacheCfg = new GenericConfigElement("nearCache"); nearCacheCfg.addAttribute("disable", Boolean.FALSE.toString()); nearCacheCfg.addAttribute("timeout", Integer.toString(clusterConfigBean.getNearCacheTimeout())); config.addChild(nearCacheCfg); } return config; } @Override public void destroy() throws Exception { if (threadPool != null) { threadPool.shutdownThreadPool(); threadPool = null; } } }