Revision: 17780
http://dcm4che.svn.sourceforge.net/dcm4che/?rev=17780&view=rev
Author: javawilli
Date: 2013-05-10 05:41:22 +0000 (Fri, 10 May 2013)
Log Message:
-----------
[#DCMEE-1715] HSM FTP/SFTP/SCP Module
Modified Paths:
--------------
dcm4chee/dcm4chee-arc/trunk/dcm4jboss-build/build.properties.default
dcm4chee/dcm4chee-arc/trunk/dcm4jboss-build/build.xml
dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/build.xml
dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/doc/BUILD
Added Paths:
-----------
dcm4chee/dcm4chee-arc/trunk/dcm4jboss-build/src/
dcm4chee/dcm4chee-arc/trunk/dcm4jboss-build/src/etc/
dcm4chee/dcm4chee-arc/trunk/dcm4jboss-build/src/etc/licenses/
dcm4chee/dcm4chee-arc/trunk/dcm4jboss-build/src/etc/licenses/LICENSE-jsch.txt
dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/etc/conf/xmdesc/dcm4chee-hsm-uri-module-xmbean.xml
dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/etc/deploy/dcm4chee-hsm-uri-module-service.xml
dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/module/uri/
dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/module/uri/Cifs.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
dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/module/uri/Uri.java
Modified: dcm4chee/dcm4chee-arc/trunk/dcm4jboss-build/build.properties.default
===================================================================
--- dcm4chee/dcm4chee-arc/trunk/dcm4jboss-build/build.properties.default 2013-05-08 11:11:00 UTC (rev 17779)
+++ dcm4chee/dcm4chee-arc/trunk/dcm4jboss-build/build.properties.default 2013-05-10 05:41:22 UTC (rev 17780)
@@ -1,5 +1,5 @@
#Override with your dcm4che-1.4.x dist location
-dcm4che14.home=${user.home}/dcm4che14/build/dcm4che-1.4.32
+dcm4che14.home=${user.home}/dcm4che14/build/dcm4che-1.4.34
#Override with your local Maven2 repository
m2.repos=${user.home}/.m2/repository
Modified: dcm4chee/dcm4chee-arc/trunk/dcm4jboss-build/build.xml
===================================================================
--- dcm4chee/dcm4chee-arc/trunk/dcm4jboss-build/build.xml 2013-05-08 11:11:00 UTC (rev 17779)
+++ dcm4chee/dcm4chee-arc/trunk/dcm4jboss-build/build.xml 2013-05-10 05:41:22 UTC (rev 17780)
@@ -4,17 +4,17 @@
<property file="build.properties"/>
<property file="../build.properties"/>
- <property name="version" value="2.17.2"/>
- <property name="audit-version" value="2.17.2"/>
+ <property name="version" value="2.18.0-SNAPSHOT"/>
+ <property name="audit-version" value="2.18.0-SNAPSHOT"/>
<property name="docstore-version" value="1.0.3"/>
- <property name="dcm4che2-version" value="2.0.26"/>
- <property name="web3-version" value="3.0.3"/>
+ <property name="dcm4che2-version" value="2.0.28-SNAPSHOT"/>
+ <property name="web3-version" value="3.0.4-SNAPSHOT"/>
<property name="target.dir" value="${basedir}/target"/>
<property name="external.dir" value="${basedir}/external"/>
<!-- Override with your dcm4che-1.4.x source dist location -->
<property name="dcm4che14.home"
- value="${user.home}/dcm4che14/build/dcm4che-1.4.33"/>
+ value="${user.home}/dcm4che14/build/dcm4che-1.4.34"/>
<!-- Override with your local Maven2 repository location -->
<property name="m2.repos" value="${user.home}/.m2/repository"/>
@@ -50,7 +50,10 @@
<!-- Override with your FOP dist location -->
<property name="fop.home" value="${user.home}/fop-0.95"/>
+ <property name="jsch.home" value="${user.home}/jsch-0.1.49"/>
+ <property name="jcifs.home" value="${user.home}/jcifs-1.3.17"/>
+
<target name="clean">
<delete dir="${target.dir}"/>
<ant inheritAll="false" dir="../dcm4jboss-ejb" target="clean"/>
@@ -151,6 +154,9 @@
<zipfileset dir="${dcm4che14.home}" prefix="${dist.db}/doc">
<include name="licenses/*"/>
</zipfileset>
+ <zipfileset dir="src/etc" prefix="${dist.db}/doc">
+ <include name="licenses/*"/>
+ </zipfileset>
<zipfileset dir="../dcm4jboss-ejb/target/common"
prefix="${dist.db.config}">
<include name="lib/*"/>
@@ -275,6 +281,12 @@
<include name="lib/commons-io-1.3.1.jar"/>
<include name="lib/xmlgraphics-commons-1.3.1.jar"/>
</zipfileset>
+ <zipfileset dir="${jsch.home}" prefix="${dist.db.config}/lib">
+ <include name="*.jar"/>
+ </zipfileset>
+ <zipfileset dir="${jcifs.home}" prefix="${dist.db.config}/lib">
+ <include name="*.jar"/>
+ </zipfileset>
<zipfileset dir="${dcm4chee-web3.ear}"
prefix="${dist.db.config}/deploy">
<include name="dcm4chee-web-ear-${web3-version}-${db.name}.ear"/>
Added: dcm4chee/dcm4chee-arc/trunk/dcm4jboss-build/src/etc/licenses/LICENSE-jsch.txt
===================================================================
--- dcm4chee/dcm4chee-arc/trunk/dcm4jboss-build/src/etc/licenses/LICENSE-jsch.txt (rev 0)
+++ dcm4chee/dcm4chee-arc/trunk/dcm4jboss-build/src/etc/licenses/LICENSE-jsch.txt 2013-05-10 05:41:22 UTC (rev 17780)
@@ -0,0 +1,30 @@
+JSch 0.0.* was released under the GNU LGPL license. Later, we have switched
+over to a BSD-style license.
+
+------------------------------------------------------------------------------
+Copyright (c) 2002-2012 Atsuhiko Yamanaka, JCraft,Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the distribution.
+
+ 3. The names of the authors may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
Modified: dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/build.xml
===================================================================
--- dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/build.xml 2013-05-08 11:11:00 UTC (rev 17779)
+++ dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/build.xml 2013-05-10 05:41:22 UTC (rev 17780)
@@ -5,7 +5,7 @@
<property file="build.properties"/>
<property file="../build.properties"/>
- <property name="version" value="2.17.1"/>
+ <property name="version" value="2.18.0-SNAPSHOT"/>
<property name="javac.debug" value="on"/>
<property name="javac.deprecation" value="off"/>
@@ -28,11 +28,15 @@
<!-- Override with your dcm4che-1.4.x source dist location -->
<property name="dcm4che14.home"
- value="${user.home}/dcm4che14/build/dcm4che-1.4.33"/>
+ value="${user.home}/dcm4che14/build/dcm4che-1.4.34"/>
<property name="dcm4che.jar" value="${dcm4che14.home}/lib/dcm4che.jar"/>
<property name="jai_imagio.jar" value="${dcm4che14.home}/lib/jai_imageio.jar"/>
<property name="slf4j-api.jar" value="${dcm4che14.home}/lib/slf4j-api-1.6.1.jar"/>
+ <!-- Override with your JSch and JCifs dist location -->
+ <property name="jsch.home" value="${user.home}/jsch-0.1.49"/>
+ <property name="jcifs.home" value="${user.home}/jcifs-1.3.17"/>
+
<!-- Override with your dcm4chee-ejb dist location -->
<property name="dcm4chee-ejb.home" value="../dcm4jboss-ejb"/>
<property name="dcm4chee-ejb.target" value="${dcm4chee-ejb.home}/target"/>
@@ -46,7 +50,7 @@
<path id="base.path">
<pathelement location="${dcm4che.jar}"/>
- <pathelement location="${jai_imagio.jar}" />
+ <pathelement location="${jai_imagio.jar}" />
<pathelement location="${slf4j-api.jar}" />
<pathelement location="${dcm4chee-ejb.target}/common/lib/dcm4chee-ejb-client.jar"/>
<pathelement location="${dcm4chee-ejb.target}/hsql/lib/dcm4chee-jdbc-hsql.jar"/>
@@ -57,6 +61,8 @@
<pathelement location="${lib.dir}/dcm4che-audit-2.0.25.jar"/>
<pathelement location="${jboss.home}/bin/"/>
<pathelement location="${jboss.home}/client/jmx-rmi-connector-client.jar"/>
+ <pathelement location="${jsch.home}/jsch-0.1.49.jar"/>
+ <pathelement location="${jcifs.home}/jcifs-1.3.17.jar"/>
<fileset dir="${jboss.home}/lib">
<include name="*.jar"/>
</fileset>
Modified: dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/doc/BUILD
===================================================================
--- dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/doc/BUILD 2013-05-08 11:11:00 UTC (rev 17779)
+++ dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/doc/BUILD 2013-05-10 05:41:22 UTC (rev 17780)
@@ -12,76 +12,82 @@
- Apache FOP 0.95 [http://xmlgraphics.apache.org/fop/]
+- JCraft JSch 0.1.49 Java Secure Channel [http://www.jcraft.com/jsch/]
+
+- Java CIFS Client Library 1.3.17 [http://jcifs.samba.org/src/]
+
- Jakarta Cactus 1.8.1 [http://jakarta.apache.org/cactus/]
(only needed to build test suite for dcm4jboss-ejb - not need to build
application)
-dcm4chee-2.17.1 archive also relies on
+dcm4chee-2.17.4 archive also relies on
-- dcm4che-1.4.31 : DICOM Library
+- dcm4che-1.4.34 : DICOM Library
which binary and source distribution package is also available at
http://sourceforge.net/projects/dcm4che. The binary package is sufficient to
build dcm4chee archive. If you download the source package, you have to build
-all components of dcm4che-1.4.31 (ant release) before building dcm4chee-2.17.1.
+all components of dcm4che-1.4.34 (ant release) before building dcm4chee-2.17.4.
-dcm4chee-2.17.1 archive also make use of
+dcm4chee-2.17.4 archive also make use of
- dcm4che-audit-logger : JMX Service for emitting DICOM Supp95 Audit Trail
Messages, and
- dcm4che-audit-login : JAAS login module emitting User Authentication message
-which sources are not included by dcm4chee-2.17.1-src.zip, but provided in a
-separate ZIP archive: dcm4chee-audit-2.17.1-src.zip at
+which sources are not included by dcm4chee-2.17.4-src.zip, but provided in a
+separate ZIP archive: dcm4chee-audit-2.17.4-src.zip at
http://sourceforge.net/projects/dcm4che. Follow the build instructions include
in dcm4chee-audit, to build and install these artifacts in your local Maven
Repository (default: ~/.m2/repository) for usage by following build task for
-dcm4chee-2.17.1 archive.
+dcm4chee-2.17.4 archive.
-dcm4chee-2.17.1 archive also make use of
+dcm4chee-2.17.4 archive also make use of
- dcm4chee-web : WEB based administration tool
-which sources are not included by dcm4chee-2.17.1-src.zip, but provided in a
-separate ZIP archive: dcm4chee-web-3.0.1-src.zip at
+which sources are not included by dcm4chee-2.17.4-src.zip, but provided in a
+separate ZIP archive: dcm4chee-web-3.0.4-src.zip at
http://sourceforge.net/projects/dcm4che. Follow the build instructions include
in dcm4chee-web, to build and install these artifacts for your appropriate database
in your local Maven Repository (default: ~/.m2/repository) for usage by following
-build task for dcm4chee-2.17.1 archive.
+build task for dcm4chee-2.17.4 archive.
-dcm4chee-2.17.1 archive also make use of
+dcm4chee-2.17.4 archive also make use of
- dcm4chee-docstore : Generic Document Storage (used by RID - Retrieve Information for Display)
-which sources are not included by dcm4chee-2.17.1-src.zip, but provided in a
-separate ZIP archive: dcm4chee-docstore-1.0.2-src.zip at
+which sources are not included by dcm4chee-2.17.4-src.zip, but provided in a
+separate ZIP archive: dcm4chee-docstore-1.0.3-src.zip at
http://sourceforge.net/projects/dcm4che. Follow the build instructions include
in dcm4chee-docstore, to build and install these artifacts in your local Maven
Repository (default: ~/.m2/repository) for usage by following build task for
-dcm4chee-2.17.1 archive.
+dcm4chee-2.17.4 archive.
-dcm4chee-2.17.1 archive has compile dependency to
+dcm4chee-2.17.4 archive has compile dependency to
- dcm4chee-xds-infoset : XDS Infoset classes (XDS Query for Consumer and Document Lifecycle)
-which sources are not included by dcm4chee-2.17.1-src.zip, but provided in a
+which sources are not included by dcm4chee-2.17.4-src.zip, but provided in a
separate ZIP archive: dcm4chee-xds-infoset-1.0.2-src.zip at
http://sourceforge.net/projects/dcm4che. Follow the build instructions include
in dcm4chee-xds-infoset, to build and install these artifacts in your local Maven
Repository (default: ~/.m2/repository) for usage by following build task for
-dcm4chee-2.17.1 archive.
+dcm4chee-2.17.4 archive.
Create an environment variable pointing to the Ant home directory (ANT_HOME)
and add the $ANT_HOME/bin directory to your PATH.
The build scripts (dcm4jboss-all/dcm4jboss-xxx/build.xml) assumes following
-locations of dcm4che-1.4.31, XDoclet, JBoss, Apache FOP, Jakarta Cactus and
+locations of dcm4che-1.4.34, XDoclet, JBoss, Apache FOP, Jsch, JCifs, Jakarta Cactus and
your local Maven2 Repository:
-dcm4che14.home=${user.home}/dcm4che14/build/dcm4che-1.4.31
+dcm4che14.home=${user.home}/dcm4che14/build/dcm4che-1.4.34
xdoclet.home=${user.home}/xdoclet-1.2.3
jboss.home=${user.home}/jboss-4.2.3.GA
fop.home=${user.home}/fop-0.95
+jsch.home=${user.home}/jsch-0.1.49
+jcifs.home=${user.home}/jcifs-1.3.17
cactus.home=${user.home}/cactus-1.8.1-bin
m2.repos=${user.home}/.m2/repository.
Added: 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 (rev 0)
+++ dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/etc/conf/xmdesc/dcm4chee-hsm-uri-module-xmbean.xml 2013-05-10 05:41:22 UTC (rev 17780)
@@ -0,0 +1,230 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mbean PUBLIC "-//JBoss//DTD JBOSS XMBEAN 1.1//EN" "http://www.jboss.org/j2ee/dtd/jboss_xmbean_1_1.dtd">
+
+<mbean>
+ <description>URI based HSM Module for File Copy Service.</description>
+
+ <descriptors>
+ <persistence persistPolicy="OnUpdate" />
+ <persistence-manager
+ value="org.jboss.mx.persistence.DelegatingPersistenceManager" />
+ </descriptors>
+
+ <class>org.dcm4chex.archive.hsm.module.uri.HSMURIModule</class>
+
+ <constructor>
+ <description>The default constructor</description>
+ <name>HSMURIModule</name>
+ </constructor>
+
+ <!-- Attributes -->
+ <attribute access="read-write" getMethod="getDestinationFilePathFormat"
+ setMethod="setDestinationFilePathFormat">
+ <description><![CDATA[Destination file path, with 'yyyy' will be replaced by the current year, 'MM' by the current month, 'dd' by the current date, 'HH' by the current hour and 'mm' by the current minute.
+ <br><code>NONE</code> = use default values (yyyy/M/d/HH) provided by system.
+ ]]>
+ </description>
+ <name>DestinationFilePathFormat</name>
+ <type>java.lang.String</type>
+ <descriptors>
+ <value value="NONE" />
+ </descriptors>
+ </attribute>
+ <attribute access="read-write" getMethod="getOutgoingDir"
+ setMethod="setOutgoingDir">
+ <description><![CDATA[Directory from which files/tarballs shall be copied
+ by external <b>CopyCommand</b>. A relative path name is resolved
+ relative to <i>archive-install-directory</i>/server/default/.]]>
+ </description>
+ <name>OutgoingDirectory</name>
+ <type>java.lang.String</type>
+ <descriptors>
+ <value value="tar-outgoing" />
+ </descriptors>
+ </attribute>
+ <attribute access="read-write" getMethod="getIncomingDir"
+ setMethod="setIncomingDir">
+ <description><![CDATA[Directory in which files/tarballs shall be retrieved
+ by external <b>FetchCommand</b>. A relative path name is resolved
+ relative to <i>archive-install-directory</i>/server/default/.]]>
+ </description>
+ <name>IncomingDirectory</name>
+ <type>java.lang.String</type>
+ <descriptors>
+ <value value="tar-incoming" />
+ </descriptors>
+ </attribute>
+ <attribute access="read-write" getMethod="getCheckCommand"
+ setMethod="setCheckCommand">
+ <description><![CDATA[External command to verify stored tar-files. Tar-file is retreived to local storage and CheckCommand is executed with tar-file as parameter. CheckCommand should exit with ZERO on succes and non-ZERO on failure. Set to <code>NONE</code> to check for existance (and filesize larger 0) only.]]>
+ </description>
+ <name>CheckCommand</name>
+ <type>java.lang.String</type>
+ <descriptors>
+ <value value="NONE" />
+ </descriptors>
+ </attribute>
+ <attribute access="read-write" getMethod="getFileStoredStatus"
+ setMethod="setFileStoredStatus">
+ <description>New file status, file is confirmed on URI.
+ Enumerated values: DEFAULT, TO_ARCHIVE, ARCHIVED,
+ QUERY_HSM_FAILED
+ </description>
+ <name>FileStoredStatus</name>
+ <type>java.lang.String</type>
+ <descriptors>
+ <value value="TO_ARCHIVE" />
+ </descriptors>
+ </attribute>
+ <attribute access="read-write" getMethod="getFileNotStoredStatus"
+ setMethod="setFileNotStoredStatus">
+ <description>New file status, file could not be confirmed on URI.
+ Enumerated values: DEFAULT, TO_ARCHIVE, ARCHIVED,
+ QUERY_HSM_FAILED
+ </description>
+ <name>FileNotStoredStatus</name>
+ <type>java.lang.String</type>
+ <descriptors>
+ <value value="DEFAULT" />
+ </descriptors>
+ </attribute>
+ <attribute access="read-write" getMethod="getSshPrivateKeyFile"
+ setMethod="setSshPrivateKeyFile">
+ <description><![CDATA[Private-key-file for ssh key-based authentication. This only applies for ssh-URIs when password is not provided. (Example: <code>id_rsa</code>)
+ ]]>
+ </description>
+ <name>SshPrivateKeyFile</name>
+ <type>java.lang.String</type>
+ <descriptors>
+ <value value="NONE" />
+ </descriptors>
+ </attribute>
+ <attribute access="read-write" getMethod="getFileCopyServiceName"
+ setMethod="setFileCopyServiceName">
+ <description>Used internally. Do NOT modify.
+ </description>
+ <name>FileCopyServiceName</name>
+ <type>javax.management.ObjectName</type>
+ </attribute>
+
+ &defaultAttributes;
+
+ <!-- Operations -->
+ &defaultOperations;
+
+ <operation impact="ACTION">
+ <description><![CDATA[Prepare File for storage to HSM. Return File Object that is used in FileCopy Service.<br/>
+ ]]></description>
+ <name>prepareHSMFile</name>
+ <parameter>
+ <description>File system ID</description>
+ <name>fsID</name>
+ <type>java.lang.String</type>
+ </parameter>
+ <parameter>
+ <description>File path relative to file system (fsID)</description>
+ <name>filePath</name>
+ <type>java.lang.String</type>
+ </parameter>
+ <return-type>java.io.File</return-type>
+ </operation>
+ <operation impact="ACTION">
+ <description>Store given File to HSM. Return filename (fileID)</description>
+ <name>storeHSMFile</name>
+ <parameter>
+ <description>File to store in HSM</description>
+ <name>file</name>
+ <type>java.io.File</type>
+ </parameter>
+ <parameter>
+ <description>File system ID</description>
+ <name>fsID</name>
+ <type>java.lang.String</type>
+ </parameter>
+ <parameter>
+ <description>File path relative to file system (fsID)</description>
+ <name>filePath</name>
+ <type>java.lang.String</type>
+ </parameter>
+ <return-type>java.lang.String</return-type>
+ </operation>
+ <operation impact="ACTION">
+ <description>Called if FileCopy failed.</description>
+ <name>failedHSMFile</name>
+ <parameter>
+ <description>File to store in HSM</description>
+ <name>file</name>
+ <type>java.io.File</type>
+ </parameter>
+ <parameter>
+ <description>File system ID</description>
+ <name>fsID</name>
+ <type>java.lang.String</type>
+ </parameter>
+ <parameter>
+ <description>File path relative to file system (fsID)</description>
+ <name>filePath</name>
+ <type>java.lang.String</type>
+ </parameter>
+ <return-type>void</return-type>
+ </operation>
+
+ <operation impact="ACTION">
+ <description>Fetch a File from HSM.</description>
+ <name>fetchHSMFile</name>
+ <parameter>
+ <description>File system ID</description>
+ <name>fsID</name>
+ <type>java.lang.String</type>
+ </parameter>
+ <parameter>
+ <description>File path relative to file system (fsID)</description>
+ <name>filePath</name>
+ <type>java.lang.String</type>
+ </parameter>
+ <return-type>java.io.File</return-type>
+ </operation>
+ <operation impact="ACTION">
+ <description>Called from TarRetriever to finish Fetch of a File from
+ HSM. (Cleanup temporary resources)</description>
+ <name>fetchHSMFileFinished</name>
+ <parameter>
+ <description>File system ID</description>
+ <name>fsID</name>
+ <type>java.lang.String</type>
+ </parameter>
+ <parameter>
+ <description>File path relative to file system (fsID)</description>
+ <name>filePath</name>
+ <type>java.lang.String</type>
+ </parameter>
+ <parameter>
+ <description>File object (returned from fetchHSMFile)</description>
+ <name>file</name>
+ <type>java.io.File</type>
+ </parameter>
+ <return-type>void</return-type>
+ </operation>
+
+ <operation impact="ACTION">
+ <description>Query status of file in HSM.</description>
+ <name>queryStatus</name>
+ <parameter>
+ <description>File system ID</description>
+ <name>fsID</name>
+ <type>java.lang.String</type>
+ </parameter>
+ <parameter>
+ <description>File path relative to file system (fsID)</description>
+ <name>filePath</name>
+ <type>java.lang.String</type>
+ </parameter>
+ <parameter>
+ <description>User info associated with the file system</description>
+ <name>userInfo</name>
+ <type>java.lang.String</type>
+ </parameter>
+ <return-type>java.lang.Integer</return-type>
+ </operation>
+</mbean>
+
Added: dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/etc/deploy/dcm4chee-hsm-uri-module-service.xml
===================================================================
--- dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/etc/deploy/dcm4chee-hsm-uri-module-service.xml (rev 0)
+++ dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/etc/deploy/dcm4chee-hsm-uri-module-service.xml 2013-05-10 05:41:22 UTC (rev 17780)
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE server PUBLIC
+ "-//JBoss//DTD MBean Service 4.2//EN"
+ "http://www.jboss.org/j2ee/dtd/jboss-service_4_2.dtd">
+
+<!-- $Id: dcm4chee-hsm-uri-module-service.xml 12644 2010-01-22 12:41:29Z gunterze $ -->
+
+<server>
+
+ <mbean code="org.dcm4chex.archive.hsm.module.uri.HSMURIModule"
+ name="dcm4chee.archive:service=FileCopyHSMModule,type=URI"
+ xmbean-dd="xmdesc/dcm4chee-hsm-uri-module-xmbean.xml">
+ <depends optional-attribute-name="FileCopyServiceName">dcm4chee.archive:service=FileCopy</depends>
+ </mbean>
+</server>
\ No newline at end of file
Added: dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/module/uri/Cifs.java
===================================================================
--- dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/module/uri/Cifs.java (rev 0)
+++ dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/module/uri/Cifs.java 2013-05-10 05:41:22 UTC (rev 17780)
@@ -0,0 +1,84 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Copyright (c) 2013 by AGFA HealthCare
+ *
+ * This file is part of dcm4che.
+ *
+ * This library 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.dcm4chex.archive.hsm.module.uri;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import jcifs.smb.SmbFile;
+import jcifs.smb.SmbFileInputStream;
+import jcifs.smb.SmbFileOutputStream;
+
+/**
+ * @author Kianusch.Sayah-Karadji@... based on work from
+ * Gunter.Zeilinger@...
+ * @version $Revision: 1.3 $
+ * @since 07.08.2003
+ */
+
+public abstract class Cifs {
+ private static void copy(InputStream in, OutputStream out) throws IOException {
+ try {
+ byte[] b = new byte[8192];
+ int n = 0;
+ while ((n = in.read(b)) > 0) {
+ out.write(b, 0, n);
+ }
+ } finally {
+ try {
+ in.close();
+ } catch (IOException e) {
+ }
+ try {
+ out.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ public static final void copyTo(final String source, final String destination) throws Exception {
+ String dDir = new SmbFile(destination).getParent();
+ if (!new SmbFile(dDir).exists()) {
+ new SmbFile(dDir).mkdirs();
+ }
+ copy(new FileInputStream(new File(source)), new SmbFileOutputStream(new SmbFile(destination)));
+ }
+
+ public static final void copyFrom(final String source, final String destination) throws Exception {
+ String dDir = new File(destination).getParent() + '/';
+ if (!new File(dDir).exists()) {
+ new File(dDir).mkdirs();
+ }
+ copy(new SmbFileInputStream(new SmbFile(source)), new FileOutputStream(new File(destination)));
+ }
+
+ public static final long fileLength(final String source) throws Exception {
+ if (new SmbFile(source).exists()) {
+ return new SmbFile(source).length();
+ }
+ return -1L;
+ }
+}
\ No newline at end of file
Added: 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 (rev 0)
+++ dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/module/uri/HSMURIModule.java 2013-05-10 05:41:22 UTC (rev 17780)
@@ -0,0 +1,233 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is part of dcm4che, an implementation of DICOM(TM) in
+ * Java(TM), available at http://sourceforge.net/projects/dcm4che.
+ *
+ * The Initial Developer of the Original Code is
+ * TIANI Medgraph AG.
+ * Portions created by the Initial Developer are Copyright (C) 2005
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Gunter Zeilinger <gunter.zeilinger@...>
+ * Franz Willer <franz.willer@...>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.dcm4chex.archive.hsm.module.uri;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.dcm4chex.archive.common.FileStatus;
+import org.dcm4chex.archive.hsm.module.AbstractHSMModule;
+import org.dcm4chex.archive.hsm.module.HSMException;
+import org.dcm4chex.archive.util.FileUtils;
+
+import org.apache.log4j.Logger;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+//@formatter:off
+/**
+ * @author kianusch.sayah-karadji@...
+ * @version $Revision: $ $Date: $
+ * @since Aug 17, 2010
+ */
+
+/*
+ * put
+ * file: /impax/server_RAD/sts/cache/tar-outgoing/F07E874F-1421814.tar
+ * fsid: tar:/impax/server_RAD/lts filePath:
+ * filePath: 2013/3/31/0/D1E8EC6C/F07E874F-1421814.tar
+ *
+ * get
+ * fsid: tar:/impax/server_RAD/lts
+ * filePath: 2007/11/10/20/43C273CF/B6769CBC-A85D7E1D.tar
+ * (destination) /impax/server_RAD/sts/cache/tar-incoming/B6769CBC-A85D7E1D.tar
+ */
+//@formatter:on
+
+public class HSMURIModule extends AbstractHSMModule {
+ private static Logger log = Logger.getLogger(HSMURIModule.class);
+
+ private String destinationFilePathFormat;
+
+ private String chkCmd;
+
+ private File sshPrivateKeyFile;
+
+ private File absSshPrivateKeyFile;
+
+ private File outgoingDir;
+
+ private File absOutgoingDir;
+
+ private File incomingDir;
+
+ private File absIncomingDir;
+
+ private int fileStoredStatus;
+
+ private int fileNotStoredStatus;
+
+ public final void setCheckCommand(String cmd) {
+ this.chkCmd = cmd;
+ }
+
+ public final String getCheckCommand() {
+ return chkCmd;
+ }
+
+ public final void setFileStoredStatus(String status) {
+ this.fileStoredStatus = FileStatus.toInt(status);
+ }
+
+ public final String getFileStoredStatus() {
+ return FileStatus.toString(fileStoredStatus);
+ }
+
+ public final void setFileNotStoredStatus(String status) {
+ this.fileNotStoredStatus = FileStatus.toInt(status);
+ }
+
+ public final String getFileNotStoredStatus() {
+ return FileStatus.toString(fileNotStoredStatus);
+ }
+
+ public final String getDestinationFilePathFormat() {
+ return destinationFilePathFormat;
+ }
+
+ public final void setDestinationFilePathFormat(String pattern) {
+ this.destinationFilePathFormat = pattern;
+ }
+
+ public final String getIncomingDir() {
+ return incomingDir.getPath();
+ }
+
+ public final void setIncomingDir(String dir) {
+ this.incomingDir = new File(dir);
+ this.absIncomingDir = FileUtils.resolve(this.incomingDir);
+ }
+
+ public final String getOutgoingDir() {
+ return outgoingDir.getPath();
+ }
+
+ public final void setOutgoingDir(String dir) {
+ this.outgoingDir = new File(dir);
+ this.absOutgoingDir = FileUtils.resolve(this.outgoingDir);
+ }
+
+ public final void setSshPrivateKeyFile(String file) {
+ this.sshPrivateKeyFile = new File(file);
+ this.absSshPrivateKeyFile = FileUtils.resolve(this.sshPrivateKeyFile);
+ }
+
+ public final String getSshPrivateKeyFile() {
+ return sshPrivateKeyFile.getPath();
+ }
+
+ @Override
+ public File prepareHSMFile(String fsID, String filePath) {
+ return new File(absOutgoingDir, new File(filePath).getName());
+ }
+
+ @Override
+ public String storeHSMFile(File file, String fsID, String filePath) throws HSMException {
+ if (destinationFilePathFormat != null && (!destinationFilePathFormat.equals("NONE"))) {
+ SimpleDateFormat sdf = new SimpleDateFormat(destinationFilePathFormat);
+ filePath = sdf.format(new Date()) + '/' + new File(filePath).getName();
+ }
+
+ try {
+ log.info("Copy to URI: " + file.getPath() + " " + stripTarIdentifier(fsID) + " " + filePath);
+ Uri.copyTo(file.getPath(), stripTarIdentifier(fsID), filePath, absSshPrivateKeyFile.getPath());
+ return filePath;
+ } catch (Exception e) {
+ throw new HSMException("copy failed...", e);
+ } finally {
+ log.info("M-DELETE " + file);
+ file.delete();
+ }
+ }
+
+ @Override
+ public void failedHSMFile(File file, String fsID, String filePath) {
+ }
+
+ @Override
+ public File fetchHSMFile(String fsID, String filePath) throws HSMException {
+ try {
+ if (absIncomingDir.mkdirs()) {
+ log.info("M-WRITE " + absIncomingDir);
+ }
+ File tarFile;
+ try {
+ tarFile = File.createTempFile("hsm_", ".tar", absIncomingDir);
+ } catch (IOException x) {
+ throw new HSMException("Failed to create temp file in " + absIncomingDir, x);
+ }
+ Uri.copyFrom(stripTarIdentifier(fsID) + '/' + filePath, tarFile.getPath(), absSshPrivateKeyFile.getPath());
+ return tarFile;
+ } catch (Exception e) {
+ throw new HSMException("fetch failed...", e);
+ }
+ }
+
+ @Override
+ public void fetchHSMFileFinished(String fsID, String filePath, File file) throws HSMException {
+ file.delete();
+ }
+
+ @Override
+ public Integer queryStatus(String fsID, String filePath, String userInfo) throws HSMException {
+ try {
+ if (chkCmd.equals("NONE")) {
+ return Uri.exists(stripTarIdentifier(fsID) + '/' + filePath, absSshPrivateKeyFile.getPath()) > 0 ? fileStoredStatus
+ : fileNotStoredStatus;
+ } else {
+ File tmpTarFile = fetchHSMFile(fsID, filePath);
+ String cmd = new String();
+ cmd = chkCmd + " " + tmpTarFile;
+ try {
+ this.doCommand(cmd, null, "URI queryStatus");
+ tmpTarFile.delete();
+ return fileStoredStatus;
+ } catch (HSMException e) {
+ if (tmpTarFile.exists())
+ tmpTarFile.delete();
+ return fileNotStoredStatus;
+ }
+ }
+ } catch (Exception e) {
+ throw new HSMException("query failed...", e);
+ }
+ }
+}
\ No newline at end of file
Added: 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 (rev 0)
+++ dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/module/uri/Ssh.java 2013-05-10 05:41:22 UTC (rev 17780)
@@ -0,0 +1,535 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Copyright (c) 2013 by AGFA HealthCare
+ *
+ * This file is part of dcm4che.
+ *
+ * This library 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.dcm4chex.archive.hsm.module.uri;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URISyntaxException;
+
+import com.jcraft.jsch.*;
+
+import org.apache.log4j.Logger;
+
+/**
+ * @author Kianusch.Sayah-Karadji@...
+ * @version $Revision: 1.3 $
+ * @since 07.08.2013
+ */
+
+public class Ssh {
+ private static Logger log = Logger.getLogger(HSMURIModule.class);
+
+ private static final byte[] ackMsg = { 0 };
+
+ private static final byte[] nackMsg = { 2, '\n' };
+
+ private static void closeQuietly(InputStream in, OutputStream out, FileInputStream fis, FileOutputStream fos) {
+ try {
+ if (fis != null)
+ fis.close();
+ } catch (IOException e) {
+ }
+ try {
+ if (fos != null)
+ fos.close();
+ } catch (IOException e) {
+ }
+ try {
+ if (out != null)
+ out.close();
+ } catch (IOException e) {
+ }
+ try {
+ if (in != null)
+ in.close();
+ } catch (IOException e) {
+ }
+ }
+
+ private static Session connect(final String uri, String identity) throws URISyntaxException, JSchException {
+ int pos = uri.indexOf("://");
+ if (pos == -1) {
+ throw new URISyntaxException("Could not parse:", uri);
+ }
+
+ String dst = null;
+
+ int pos2 = uri.indexOf('/', pos + 3);
+ if (pos2 > -1) {
+ dst = uri.substring(pos + 3, pos2);
+ } else {
+ dst = uri.substring(pos + 3);
+ }
+
+ String username = null;
+ String password = null;
+ String host = null;
+ int port = 22;
+
+ pos = dst.indexOf('@');
+ if (pos != -1) {
+ username = dst.substring(0, pos);
+ host = dst.substring(pos + 1);
+
+ pos = username.indexOf(':');
+ if (pos != -1) {
+ password = username.substring(pos + 1);
+ username = username.substring(0, pos);
+ }
+
+ pos = host.indexOf(':');
+ if (pos != -1) {
+ port = Integer.parseInt(host.substring(pos + 1));
+ host = host.substring(0, pos);
+ }
+ } else {
+ throw new URISyntaxException("Could not parse:", uri);
+ }
+
+ JSch jsch = new JSch();
+ JSch.setConfig("StrictHostKeyChecking", "no");
+ if (password == null && identity != null && (!identity.equals("NONE")))
+ jsch.addIdentity(identity);
+ Session session = jsch.getSession(username, host, port);
+ if (password != null)
+ session.setPassword(password);
+ session.connect();
+ return session;
+ }
+
+ private static int checkAck(InputStream in) throws IOException {
+ int b = in.read();
+ // b may be
+ // 0 for success,
+ // 1 for error,
+ // 2 for fatal error,
+ // -1
+
+ // // next 4 lines are for speed
+ // if (b == 0)
+ // return b;
+ // if (b == -1)
+ // return b;
+
+ if (b == 1 || b == 2) {
+ StringBuffer sb = new StringBuffer();
+ int c;
+ do {
+ c = in.read();
+ sb.append((char) c);
+ } while (c != '\n');
+ log.error(sb.toString());
+ }
+ return b;
+ }
+
+ private static void sendCommand(OutputStream out, InputStream in, String command) throws IOException, JSchException {
+ out.write(command.getBytes());
+ out.flush();
+ if (checkAck(in) != 0) {
+ throw new JSchException();
+ }
+ }
+
+ private static String getPath(final String uri, final boolean source) throws URISyntaxException {
+ int pos = uri.indexOf('/', uri.indexOf("://") + 3);
+
+ if (pos == -1) {
+ if (source != true)
+ return "/";
+ throw new URISyntaxException("URI should not end with '/'.", uri);
+ }
+
+ String path = uri.substring(pos);
+
+ if (path.equals("/~")) {
+ if (source != true)
+ return ".";
+ throw new URISyntaxException("URI should not end with '~'.", uri);
+ }
+
+ if (path.endsWith("/")) {
+ if (path.equals("/~/") && (source != true))
+ return "./";
+ throw new URISyntaxException("URI should not end with '/'.", uri);
+ }
+
+ if (path.startsWith("/~/"))
+ return path.substring(3);
+
+ return path;
+ }
+
+ public static void exec(final String cmdUri, final String identity) throws URISyntaxException, JSchException,
+ IOException {
+ Session session = null;
+ try {
+ session = connect(cmdUri, identity);
+ if (session != null) {
+ exec(session, cmdUri.substring(cmdUri.indexOf('/', cmdUri.indexOf("://") + 3) + 1));
+ }
+ } finally {
+ if (session != null) {
+ session.disconnect();
+ }
+ }
+ }
+
+ private static void exec(final Session session, final String cmd) throws JSchException, IOException {
+ InputStream in = null;
+ Channel channel = session.openChannel("exec");
+ boolean foo = false;
+
+ try {
+ ((ChannelExec) channel).setCommand(cmd);
+
+ channel.setInputStream(null);
+ // ((ChannelExec) channel).setErrStream(System.err);
+ in = channel.getInputStream();
+
+ // channel.setInputStream(System.in);
+ // channel.setOutputStream(System.out);
+
+ // FileOutputStream fos=new FileOutputStream("/tmp/stderr");
+ // ((ChannelExec)channel).setErrStream(fos);
+ channel.connect();
+
+ byte[] tmp = new byte[1024];
+ while (true) {
+ while (in.available() > 0) {
+ int i = in.read(tmp, 0, 1024);
+ if (i < 0)
+ break;
+ System.out.print(new String(tmp, 0, i));
+ }
+ if (channel.isClosed()) {
+ if (channel.getExitStatus() != 0) {
+ foo = true;
+ }
+ break;
+ }
+ try {
+ Thread.sleep(1000);
+ } catch (Exception ee) {
+ }
+ }
+ } finally {
+ closeQuietly(in, null, null, null);
+ channel.disconnect();
+ }
+ if (foo) {
+ throw new JSchException("SSH Exec Error");
+ }
+ }
+
+ public static void scpCopyTo(String source, String destinationUrl, String destination, String identity)
+ throws URISyntaxException, JSchException, IOException {
+ String basePath = getPath(destinationUrl, false);
+
+ Session session = connect(destinationUrl, identity);
+ Channel channel = session.openChannel("exec");
+
+ FileInputStream fis = null;
+ OutputStream out = null;
+ InputStream in = null;
+
+ try {
+ String dDir = new File(destination).getParent();
+ String dFile = new File(destination).getName();
+
+ String command = "scp -t -r " + basePath;
+ ((ChannelExec) channel).setCommand(command);
+ out = channel.getOutputStream();
+ in = channel.getInputStream();
+
+ channel.connect();
+
+ if (checkAck(in) != 0) {
+ throw new JSchException();
+ }
+
+ // prepend remote directory with "."
+ if (dDir == null) {
+ dDir = ".";
+ } else {
+ dDir = "./" + dDir;
+ }
+
+ int cnt = 0;
+ // create and decent into directory structure - and count decent
+ String[] folders = dDir.split("/");
+ for (String folder : folders) {
+ if (folder.length() > 0) {
+ cnt++;
+ sendCommand(out, in, "D0755 0 " + folder + "\n");
+ }
+ }
+
+ File _lfile = new File(source);
+ long filesize = _lfile.length();
+ sendCommand(out, in, "C0644 " + filesize + " " + dFile + "\n");
+
+ fis = new FileInputStream(source);
+ byte[] buf = new byte[1024];
+ while (true) {
+ int len = fis.read(buf, 0, buf.length);
+ if (len <= 0)
+ break;
+ out.write(buf, 0, len); // out.flush();
+ }
+
+ out.write(ackMsg, 0, 1);
+ out.flush();
+
+ if (checkAck(in) != 0) {
+ throw new JSchException();
+ }
+
+ // remotly "close" open directories
+ while (cnt-- > 0) {
+ sendCommand(out, in, "E\n");
+ }
+
+ } finally {
+ closeQuietly(in, out, fis, null);
+ channel.disconnect();
+ session.disconnect();
+ }
+ }
+
+ public static void scpCopyFrom(final String source, final String destination, String identity) throws Exception {
+ String sPath = getPath(source, true);
+
+ Session session = connect(source, identity);
+
+ Channel channel = session.openChannel("exec");
+
+ FileOutputStream fos = null;
+ OutputStream out = null;
+ InputStream in = null;
+ try {
+ String dDir = new File(destination).getParent() + "/";
+ // create destination
+ if (!new File(dDir).exists()) {
+ new File(dDir).mkdirs();
+ }
+
+ String command = "scp -f " + sPath;
+ ((ChannelExec) channel).setCommand(command);
+
+ // get I/O streams for remote scp
+ out = channel.getOutputStream();
+ in = channel.getInputStream();
+
+ channel.connect();
+
+ out.write(ackMsg, 0, 1);
+ out.flush();
+
+ byte[] buf = new byte[1024];
+
+ long filesize = scpGetHeader(in);
+
+ if (filesize > -1) {
+ out.write(ackMsg, 0, 1);
+ out.flush();
+
+ fos = new FileOutputStream(destination);
+ int foo;
+ while (true) {
+ if (buf.length < filesize)
+ foo = buf.length;
+ else
+ foo = (int) filesize;
+ foo = in.read(buf, 0, foo);
+ if (foo < 0) {
+ // error
+ break;
+ }
+ fos.write(buf, 0, foo);
+ filesize -= foo;
+ if (filesize == 0L)
+ break;
+ }
+
+ if (checkAck(in) != 0) {
+ throw new Exception();
+ }
+
+ out.write(ackMsg, 0, 1);
+ out.flush();
+ }
+ } finally {
+ closeQuietly(in, out, null, fos);
+ channel.disconnect();
+ session.disconnect();
+ }
+ }
+
+ public static long scpFileLength(String uri, String identity) throws Exception {
+ String sPath = getPath(uri, true);
+
+ Session session = connect(uri, identity);
+ Channel channel = session.openChannel("exec");
+
+ OutputStream out = null;
+ InputStream in = null;
+
+ long filesize = -1L;
+
+ try {
+ String command = "scp -f " + sPath;
+ ((ChannelExec) channel).setCommand(command);
+
+ // get I/O streams for remote scp
+ out = channel.getOutputStream();
+ in = channel.getInputStream();
+
+ channel.connect();
+
+ out.write(ackMsg, 0, 1);
+ out.flush();
+
+ filesize = scpGetHeader(in);
+
+ // After getting filesize, we do not care about file content - so we
+ // send an error message to abort the connection
+ out.write(nackMsg, 0, 2);
+ out.flush();
+ } finally {
+ closeQuietly(in, out, null, null);
+ channel.disconnect();
+ session.disconnect();
+ }
+
+ return filesize;
+ }
+
+ private static long scpGetHeader(InputStream in) throws IOException {
+ long filesize = 0;
+ byte[] buf = new byte[512];
+
+ if (checkAck(in) != 'C') {
+ return -1L;
+ }
+
+ // read '0644 '
+ in.read(buf, 0, 5);
+
+ while (true) {
+ if (in.read(buf, 0, 1) < 0) {
+ // error
+ break;
+ }
+ if (buf[0] == ' ')
+ break;
+ filesize = filesize * 10L + (long) (buf[0] - '0');
+ }
+
+ // skip filename
+ for (int i = 0;; i++) {
+ in.read(buf, i, 1);
+ if (buf[i] == (byte) 0x0a) {
+ break;
+ }
+ }
+
+ return filesize;
+ }
+
+ public static void sftpCopyTo(String source, String destinationUrl, String destination, String identity)
+ throws Exception {
+ String basePath = getPath(destinationUrl, false);
+
+ if (basePath.endsWith("/") && (basePath.length() > 1)) {
+ throw new URISyntaxException("Destination SSH/SFTP-URL (" + destinationUrl + ") should not end with '/'.",
+ destinationUrl);
+ }
+
+ Session session = connect(destinationUrl, identity);
+ String dDir = new File(destination).getParent();
+ String dFile = new File(destination).getName();
+
+ Channel channel = session.openChannel("sftp");
+ channel.connect();
+ ChannelSftp channelSftp = (ChannelSftp) channel;
+ channelSftp.cd(basePath);
+ if (dDir != null) {
+ String[] folders = dDir.split("/");
+ for (String folder : folders) {
+ if (folder.length() > 0) {
+ try {
+ channelSftp.cd(folder);
+ } catch (SftpException e) {
+ channelSftp.mkdir(folder);
+ channelSftp.cd(folder);
+ }
+ }
+ }
+ }
+ channelSftp.put(source, dFile);
+ channelSftp.disconnect();
+ channel.disconnect();
+ session.disconnect();
+ }
+
+ public static void sftpCopyFrom(String source, String destination, String identity) throws Exception {
+ String src = getPath(source, true);
+
+ Session session = connect(source, identity);
+ String dDir = new File(destination).getParent() + "/";
+ if (!new File(dDir).exists()) {
+ new File(dDir).mkdirs();
+ }
+
+ Channel channel = session.openChannel("sftp");
+ channel.connect();
+ ChannelSftp channelSftp = (ChannelSftp) channel;
+ channelSftp.get(src, destination);
+ channelSftp.disconnect();
+ channel.disconnect();
+ session.disconnect();
+ }
+
+ public static long sftpFileLength(String source, String identity) throws Exception {
+ String src = getPath(source, true);
+
+ Session session = connect(source, identity);
+ Channel channel = session.openChannel("sftp");
+ channel.connect();
+ ChannelSftp channelSftp = (ChannelSftp) channel;
+ long fsize = -1L;
+ try {
+ SftpATTRS attrs = channelSftp.lstat(src);
+ fsize = attrs.getSize();
+ } catch (Exception e) {
+ }
+ channelSftp.disconnect();
+ channel.disconnect();
+ session.disconnect();
+ return fsize;
+ }
+}
\ No newline at end of file
Added: dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/module/uri/Uri.java
===================================================================
--- dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/module/uri/Uri.java (rev 0)
+++ dcm4chee/dcm4chee-arc/trunk/dcm4jboss-sar/src/java/org/dcm4chex/archive/hsm/module/uri/Uri.java 2013-05-10 05:41:22 UTC (rev 17780)
@@ -0,0 +1,119 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Copyright (c) 2013 by AGFA HealthCare
+ *
+ * This file is part of dcm4che.
+ *
+ * This library 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.dcm4chex.archive.hsm.module.uri;
+
+import java.io.File;
+import java.net.URISyntaxException;
+
+public class Uri {
+ private final class SCHEMES {
+ public final static int UNKNOWN = 0;
+
+ // Local
+ @SuppressWarnings("unused")
+ public final static int FILE = 1;
+
+ // SMB/CIFS
+ public final static int CIFS = 2;
+
+ // SSH/SCP
+ public final static int SSH = 3;
+
+ // SFTP
+ public final static int SFTP = 4;
+
+ // RSH/RCMD/RCP
+ public final static int RSH = 5;
+ }
+
+ public static int isUri(String uri) {
+ if (uri.startsWith("ssh://") || uri.startsWith("scp://"))
+ return SCHEMES.SSH;
+ if (uri.startsWith("sftp://"))
+ return SCHEMES.SFTP;
+ if (uri.startsWith("rsh://") || uri.startsWith("rcp://"))
+ return SCHEMES.RSH;
+ if (uri.startsWith("smb://"))
+ return SCHEMES.CIFS;
+ // if (uri.startsWith("file://"))
+ // return Schemes.File;
+ return SCHEMES.UNKNOWN;
+ }
+
+ protected static void copyFrom(String src, String dst, String identity) throws Exception {
+ switch (isUri(src)) {
+ case SCHEMES.SSH:
+ Ssh.scpCopyFrom(src, dst, identity);
+ break;
+ case SCHEMES.SFTP:
+ Ssh.sftpCopyFrom(src, dst, identity);
+ break;
+ case SCHEMES.CIFS:
+ Cifs.copyFrom(src, dst);
+ break;
+ default:
+ throw new URISyntaxException("Unknown URI:", src);
+ }
+ }
+
+ protected static void copyTo(String src, String dstUrl, String dst, String identity) throws Exception {
+ switch (isUri(dstUrl)) {
+ case SCHEMES.SSH:
+ Ssh.scpCopyTo(src, dstUrl, dst, identity);
+ break;
+ case SCHEMES.SFTP:
+ Ssh.sftpCopyTo(src, dstUrl, dst, identity);
+ break;
+ case SCHEMES.CIFS:
+ Cifs.copyTo(src, dstUrl + "/" + dst);
+ break;
+ default:
+ throw new URISyntaxException("Unknown URI:", dstUrl);
+ }
+ }
+
+ protected static void exec(String cmdUri, String identity) throws Exception {
+ switch (isUri(cmdUri)) {
+ case SCHEMES.SSH:
+ Ssh.exec(cmdUri, identity);
+ break;
+ default:
+ throw new URISyntaxException("Unknown URI:", cmdUri);
+ }
+ }
+
+ public static long exists(String uri, String identity) throws Exception {
+ switch (isUri(uri)) {
+ case SCHEMES.SSH:
+ return Ssh.scpFileLength(uri, identity);
+ case SCHEMES.SFTP:
+ return Ssh.sftpFileLength(uri, identity);
+ case SCHEMES.CIFS:
+ return Cifs.fileLength(uri);
+ default:
+ if (new File(uri).exists()) {
+ return new File(uri).length();
+ }
+ }
+ return -1;
+ }
+}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|