From: <jav...@us...> - 2016-05-30 12:56:54
|
Revision: 18608 http://sourceforge.net/p/dcm4che/svn/18608 Author: javawilli Date: 2016-05-30 12:56:52 +0000 (Mon, 30 May 2016) Log Message: ----------- [DCMEE-2137] URI HSM module:Add possibility to get sub-directory from remote system. Modified Paths: -------------- dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/etc/conf/xmdesc/dcm4chee-hsm-uri-module-xmbean.xml dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/FileCopyService.java dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/module/uri/HSMURIModule.java dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/module/uri/Ssh.java Modified: dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/etc/conf/xmdesc/dcm4chee-hsm-uri-module-xmbean.xml =================================================================== --- dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/etc/conf/xmdesc/dcm4chee-hsm-uri-module-xmbean.xml 2016-05-30 12:55:31 UTC (rev 18607) +++ dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/etc/conf/xmdesc/dcm4chee-hsm-uri-module-xmbean.xml 2016-05-30 12:56:52 UTC (rev 18608) @@ -59,6 +59,45 @@ <value value="NONE" /> </descriptors> </attribute> + <attribute access="read-write" getMethod="getDetermineSubdirCmd" + setMethod="setDetermineSubdirCmd"> + <description><![CDATA[Command to get a subdirectory to store a hsm file. This can be used to determine the path with sufficiant free space on the target system.<br/> + Format: [ssh://[username[:password]]@host[:port]/]<commando [{0}] [{1}]><br/> + {0} : current subdirectory<br/> + {1} : minFreeSubdir in bytes <br /> + If ssh:// is not given, this information is taken from the target filesystemID.<br/> + The command should write 'subdir=<subdirectory name>' to stdout.<br/> + To limit calls of this command, the available free disk space can be also used by writing 'avail=<available free space in bytes>' in an extra line to stdout.<br/> + In this case the next determineSubDirCmd is called after 3/4 of this available space is stored to this subdirectory. + ]]> + </description> + <name>DetermineSubdirCmd</name> + <type>java.lang.String</type> + <descriptors> + <value value="NONE" /> + </descriptors> + </attribute> + <attribute access="read-write" getMethod="getMinFreeSubdir" + setMethod="setMinFreeSubdir"> + <description><![CDATA[Minimum disk free space of sub-directory. this value (in bytes) can be used as parameter {1} in <code>DetermineSubdirCmd</code> + ]]> + </description> + <name>MinFreeOfSubdir</name> + <type>java.lang.String</type> + <descriptors> + <value value="100MB" /> + </descriptors> + </attribute> + <attribute access="read-only" getMethod="getCurrentSubdir"> + <description>Current selected sub-directory</description> + <name>CurrentSubdir</name> + <type>java.lang.String</type> + </attribute> + <attribute access="read-only" getMethod="getAvailOnCurrentSubdir"> + <description>Available disk space on current sub-directory</description> + <name>AvailableOnCurrentSubdir</name> + <type>java.lang.String</type> + </attribute> <attribute access="read-write" getMethod="getOutgoingDir" setMethod="setOutgoingDir"> <description><![CDATA[Directory from which files/tarballs shall be copied @@ -273,5 +312,15 @@ </parameter> <return-type>java.lang.Integer</return-type> </operation> + <operation impact="ACTION"> + <description>Determine a sub directory on remote system that is used for storeHSMFile.</description> + <name>determineSubDir</name> + <parameter> + <description>Command performed via ssh on remote system. e.g.: "ssh://username:passwd@host:port/etc/getsubdir.sh</description> + <name>command</name> + <type>java.lang.String</type> + </parameter> + <return-type>java.util.Properties</return-type> + </operation> </mbean> Modified: dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/FileCopyService.java =================================================================== --- dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/FileCopyService.java 2016-05-30 12:55:31 UTC (rev 18607) +++ dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/FileCopyService.java 2016-05-30 12:56:52 UTC (rev 18608) @@ -196,7 +196,7 @@ } protected BaseJmsOrder createOrder(Dataset ian) { - FileCopyOrder fileCopyOrder = new FileCopyOrder(ian, ForwardingRules.toAET(destination), + FileCopyOrder fileCopyOrder = new FileCopyOrder(ian, destination, getRetrieveAETs(), getFetchSize()); fileCopyOrder.processOrderProperties(); Modified: dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/module/uri/HSMURIModule.java =================================================================== --- dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/module/uri/HSMURIModule.java 2016-05-30 12:55:31 UTC (rev 18607) +++ dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/module/uri/HSMURIModule.java 2016-05-30 12:56:52 UTC (rev 18608) @@ -48,11 +48,13 @@ import org.dcm4chex.archive.util.FileUtils; import org.apache.log4j.Logger; +import java.text.MessageFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Map; +import java.util.Properties; import java.util.StringTokenizer; //@formatter:off @@ -80,6 +82,8 @@ private String destinationFilePathFormat; + private String determineSubdirCmd; + private String chkCmd; private File sshPrivateKeyFile; @@ -106,6 +110,10 @@ private int[] retentionTime = new int[2]; private String cifsRetentionTimes; + + private String currentSubdir; + private long availOnCurrentSubdir = 0l; + private long minFreeSubdir; private static final String CAL_FIELD_NAMES = "yMd"; @@ -145,7 +153,31 @@ this.destinationFilePathFormat = pattern; } - public final String getIncomingDir() { + public String getDetermineSubdirCmd() { + return determineSubdirCmd == null ? NONE : determineSubdirCmd; + } + + public void setDetermineSubdirCmd(String determineSubdirCmd) { + this.determineSubdirCmd = NONE.equals(determineSubdirCmd) ? null : determineSubdirCmd; + } + + public final String getMinFreeSubdir() { + return FileUtils.formatSize(minFreeSubdir); + } + + public final void setMinFreeSubdir(String s) { + this.minFreeSubdir = FileUtils.parseSize(s, 0); + } + + public String getCurrentSubdir() { + return currentSubdir == null ? "N.A." : currentSubdir; + } + + public String getAvailOnCurrentSubdir() { + return currentSubdir == null ? "N.A." : FileUtils.formatSize(availOnCurrentSubdir); + } + + public final String getIncomingDir() { return incomingDir.getPath(); } @@ -207,7 +239,7 @@ setAccessTimeAfterSetReadonly = s.charAt(0) == '+'; retentionTime[0] = Integer.parseInt(s.substring(setAccessTimeAfterSetReadonly ? 1 : 0, --len)); if (retentionTime[0] == 0) { - retentionTime[1] = -1; + retentionTime[1] = 2; } else { int idx = CAL_FIELD_NAMES.indexOf(s.charAt(len)); if (idx < 0 || idx > 2) { @@ -246,10 +278,40 @@ SimpleDateFormat sdf = new SimpleDateFormat(destinationFilePathFormat); filePath = sdf.format(new Date()) + '/' + new File(filePath).getName(); } - + if (determineSubdirCmd != null) { + if (currentSubdir == null || this.availOnCurrentSubdir < file.length()) { + try { + String cmd = MessageFormat.format(determineSubdirCmd, currentSubdir, String.valueOf(minFreeSubdir)); + log.debug("Determine sub directory with command "+cmd); + Properties p = Ssh.getSubdir(stripTarIdentifier(fsID), cmd, absSshPrivateKeyFile.getPath()); + if (!"0".equals(p.getProperty(Ssh.EXIT_STATUS)) || p.getProperty("subdir") == null) { + throw new RuntimeException("determineSubdirCmd was not successful! exit status:"+p.getProperty(Ssh.EXIT_STATUS)); + } + String subdir = p.getProperty("subdir"); + log.debug("Determined subdirectory:"+subdir); + currentSubdir = subdir; + String avail = p.getProperty("avail"); + if (avail != null) { + try { + availOnCurrentSubdir = Long.parseLong(avail); + availOnCurrentSubdir = availOnCurrentSubdir - (availOnCurrentSubdir >> 2); + log.debug("availOnCurrentSubdir:"+availOnCurrentSubdir); + } catch (Exception ignore) { + log.warn("Failed to parse property 'avail' value='"+avail+"'! availOnCurrentSubdir not changed!"); + } + } + } catch (Exception e) { + throw new HSMException("copy failed...", e); + } + } + filePath = currentSubdir + "/" + filePath; + } try { log.info("Copy to URI: " + file.getPath() + " " + stripTarIdentifier(fsID) + " " + filePath); Uri.copyTo(file.getPath(), stripTarIdentifier(fsID), filePath, absSshPrivateKeyFile.getPath(), getRetentionDate(), setAccessTimeAfterSetReadonly, cifsRetentionTimes); + if (this.availOnCurrentSubdir > 0l) { + availOnCurrentSubdir -= file.length(); + } return filePath; } catch (Exception e) { throw new HSMException("copy failed...", e); @@ -316,4 +378,12 @@ } } + public Properties determineSubDir(String cmd) throws Exception { + return Ssh.getSubdir(null, cmd, absSshPrivateKeyFile.getPath()); + } + + public void resetCurrentSubdir() { + this.currentSubdir = null; + this.availOnCurrentSubdir = 0l; + } } \ No newline at end of file Modified: dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/module/uri/Ssh.java =================================================================== --- dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/module/uri/Ssh.java 2016-05-30 12:55:31 UTC (rev 18607) +++ dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/module/uri/Ssh.java 2016-05-30 12:56:52 UTC (rev 18608) @@ -28,6 +28,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.URISyntaxException; +import java.util.Properties; import com.jcraft.jsch.*; @@ -40,8 +41,10 @@ */ public class Ssh { - private static Logger log = Logger.getLogger(HSMURIModule.class); + protected static final String EXIT_STATUS = "exit_status"; + private static Logger log = Logger.getLogger(HSMURIModule.class); + private static final byte[] ackMsg = { 0 }; private static final byte[] nackMsg = { 2, '\n' }; @@ -547,4 +550,39 @@ session.disconnect(); return fsize; } + + public static Properties getSubdir(String destURI, String subdirCmd, String identity) throws Exception { + Session session = null; + Channel channel = null; + InputStream is = null; + Properties p = new Properties(); + try { + int pos = subdirCmd.indexOf("://"); + if (pos == -1) { + if (destURI == null) + throw new IllegalArgumentException("subdirCmd has no host information and destURI is not given!"); + session = connect(destURI, identity); + } else { + session = connect(subdirCmd, identity); + subdirCmd = subdirCmd.substring(subdirCmd.indexOf('/', pos+3)); + } + channel = session.openChannel("exec"); + ((ChannelExec) channel).setCommand(subdirCmd); + is = channel.getInputStream(); + channel.connect(); + p.load(is); + p.setProperty(EXIT_STATUS, String.valueOf(channel.getExitStatus())); + } finally { + if (channel != null) + channel.disconnect(); + if (session != null) + session.disconnect(); + if (is != null) try { + is.close(); + } catch (IOException ignore) {} + } + return p; + } + + } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |