001 /*
002 *
003 * $Revision: 13085 $ $Date: 2008-02-06 18:27:24 +0100 (Mi, 06 Feb 2008) $
004 *
005 * This file is part of *** M y C o R e ***
006 * See http://www.mycore.de/ for details.
007 *
008 * This program is free software; you can use it, redistribute it
009 * and / or modify it under the terms of the GNU General Public License
010 * (GPL) as published by the Free Software Foundation; either version 2
011 * of the License or (at your option) any later version.
012 *
013 * This program is distributed in the hope that it will be useful, but
014 * WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program, in a file called gpl.txt or license.txt.
020 * If not, write to the Free Software Foundation Inc.,
021 * 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
022 */
023
024 package org.mycore.backend.videocharger;
025
026 import java.io.ByteArrayInputStream;
027 import java.io.ByteArrayOutputStream;
028 import java.io.File;
029 import java.io.FileOutputStream;
030 import java.io.InputStream;
031 import java.io.OutputStream;
032
033 import org.apache.log4j.Logger;
034 import org.mycore.common.MCRConfiguration;
035 import org.mycore.common.MCRPersistenceException;
036 import org.mycore.datamodel.ifs.MCRContentInputStream;
037 import org.mycore.datamodel.ifs.MCRContentStore;
038 import org.mycore.datamodel.ifs.MCRFileReader;
039
040 import com.enterprisedt.net.ftp.FTPClient;
041 import com.enterprisedt.net.ftp.FTPTransferType;
042
043 /**
044 * This class implements the MCRContentStore interface to store the content of
045 * MCRFile objects in IBM VideoCharger Server. This allows the content to be
046 * streamed. This implementation uses FTP to manage the files in VideoCharger.
047 * The FTP connection parameters are configured in mycore.properties:
048 *
049 * <code>
050 * MCR.IFS.ContentStore.<StoreID>.Hostname Hostname of VideoCharger Server
051 * MCR.IFS.ContentStore.<StoreID>.FTPPort Port of VideoCharger FTP interface, default is 4324
052 * MCR.IFS.ContentStore.<StoreID>.UserID User ID for FTP connections, e. g. vsloader
053 * MCR.IFS.ContentStore.<StoreID>.Password Password for this user
054 * MCR.IFS.ContentStore.<StoreID>.DebugFTP If true, FTP debug messages are written to stdout, default is false
055 * MCR.IFS.ContentStore.<StoreID>.AssetGroup Asset group, default is 'AG'
056 * </code>
057 *
058 * This class also provides a method to backup all assets stored in VideoCharger
059 * to a directory.
060 *
061 * @author Frank Lützenkirchen
062 * @version $Revision: 13085 $ $Date: 2008-02-06 18:27:24 +0100 (Mi, 06 Feb 2008) $
063 *
064 * @see MCRAVExtVideoCharger
065 */
066 public class MCRCStoreVideoCharger extends MCRContentStore {
067 private static Logger logger = Logger.getLogger(MCRCStoreVideoCharger.class.getName());
068
069 /** Hostname of VideoCharger server */
070 protected String host;
071
072 /** Port of VideoCharger server FTP interface */
073 protected int port;
074
075 /** User ID for FTP login */
076 protected String user;
077
078 /** Password for FTP login */
079 protected String password;
080
081 /** If true, FTP debug messages are written to stdout */
082 protected boolean debugFTP;
083
084 /** Asset group **/
085 protected String assetGroup;
086
087 /** FTP Return code if "quote site avs attr" is successful */
088 protected final static String[] ok = { "200" };
089
090 public void init(String storeID) {
091 super.init(storeID);
092
093 MCRConfiguration config = MCRConfiguration.instance();
094
095 host = config.getString(prefix + "Hostname");
096 port = config.getInt(prefix + "FTPPort", 4324);
097 user = config.getString(prefix + "UserID");
098 password = config.getString(prefix + "Password");
099 debugFTP = config.getBoolean(prefix + "DebugFTP", false);
100 assetGroup = config.getString(prefix + "AssetGroup", "AG" );
101 }
102
103 protected String doStoreContent(MCRFileReader file, MCRContentInputStream source) throws Exception {
104 String storageID = buildNextID(file);
105
106 FTPClient connection = connect();
107
108 try {
109 connection.quote("site avs attr assetgroup=" + assetGroup, ok);
110 connection.quote("site avs attr title=" + storageID, ok);
111 connection.put(source, storageID);
112
113 return storageID;
114 } finally {
115 disconnect(connection);
116 }
117 }
118
119 protected void doDeleteContent(String storageID) throws Exception {
120 FTPClient connection = connect();
121
122 try {
123 connection.quote("site avs attr assetgroup=" + assetGroup, ok);
124 connection.delete(storageID);
125 } finally {
126 disconnect(connection);
127 }
128 }
129
130 protected void doRetrieveContent(MCRFileReader file, OutputStream target) throws Exception {
131 retrieveContent(file.getStorageID(), target);
132 }
133
134 protected InputStream doRetrieveContent(MCRFileReader file) throws Exception {
135 //FTPClient does not provide GET and InputStreams, we need to copy
136 ByteArrayOutputStream bout=new ByteArrayOutputStream();
137 doRetrieveContent(file, bout);
138 bout.close();
139 return new ByteArrayInputStream(bout.toByteArray());
140 }
141
142 protected void retrieveContent(String assetID, OutputStream target) throws Exception {
143 FTPClient connection = connect();
144
145 try {
146 connection.quote("site avs attr assetgroup=" + assetGroup, ok);
147 connection.get(target, assetID);
148 } finally {
149 disconnect(connection);
150 }
151 }
152
153 /**
154 * Reads all assets stored in VideoCharger server and writes the contents to
155 * a directory for backup. If the directory already contains an asset with
156 * the same name, that assets is skipped and not backed up.
157 *
158 * @param storeID
159 * the store ID fo the VideoCharger store to be backed up
160 * @param directory
161 * the local directory to write the assets to
162 */
163 public static void backupContentTo(String storeID, String directory) throws MCRPersistenceException, Exception {
164 MCRAVExtVideoCharger extender = new MCRAVExtVideoCharger();
165 extender.readConfig(storeID);
166 MCRCStoreVideoCharger store = new MCRCStoreVideoCharger();
167 store.init( storeID );
168
169 String[] list = extender.listAssets();
170
171 for (int i = 0; i < list.length; i++) {
172 logger.info("Backup of asset with ID = " + list[i]);
173
174 File local = new File(directory, list[i]);
175
176 if (local.exists()) {
177 continue;
178 }
179
180 FileOutputStream target = new FileOutputStream(local);
181 store.retrieveContent(list[i], target);
182 target.close();
183 }
184 }
185
186 /**
187 * Connects to IBM VideoCharger Server via FTP
188 */
189 protected FTPClient connect() throws MCRPersistenceException {
190 try {
191 FTPClient connection = new FTPClient(host, port);
192 connection.debugResponses(debugFTP);
193 connection.login(user, password);
194 connection.setType(FTPTransferType.BINARY);
195
196 return connection;
197 } catch (Exception exc) {
198 String msg = "Could not connect to " + host + ":" + port + " via FTP";
199 throw new MCRPersistenceException(msg, exc);
200 }
201 }
202
203 /**
204 * Closes the FTP connection to VideoCharger server
205 *
206 * @param connection
207 * the FTP connection to close
208 */
209 protected void disconnect(FTPClient connection) {
210 try {
211 connection.quit();
212 } catch (Exception ignored) {
213 }
214 }
215 }