Java tutorial
/* * * ==================================================================== * * Copyright (C) 2007-2008 GeoSolutions S.A.S. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. * * ==================================================================== * * This software consists of voluntary contributions made by developers * of GeoSolutions. For more information on GeoSolutions, please see * <http://www.geo-solutions.it/>. * */ package it.geosolutions.geobatch.ftpserver.server; import it.geosolutions.filesystemmonitor.monitor.FileSystemEvent; import it.geosolutions.filesystemmonitor.monitor.FileSystemEventType; import it.geosolutions.geobatch.catalog.Catalog; import it.geosolutions.geobatch.flow.file.FileBasedFlowManager; import it.geosolutions.geobatch.global.CatalogHolder; import java.io.File; import java.io.IOException; import org.apache.commons.io.FilenameUtils; import org.apache.ftpserver.ftplet.DefaultFtpReply; import org.apache.ftpserver.ftplet.FtpException; import org.apache.ftpserver.ftplet.FtpReply; import org.apache.ftpserver.ftplet.FtpRequest; import org.apache.ftpserver.ftplet.FtpSession; import org.apache.ftpserver.ftplet.FtpStatistics; import org.apache.ftpserver.ftplet.Ftplet; import org.apache.ftpserver.ftplet.FtpletContext; import org.apache.ftpserver.ftplet.FtpletResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author ETj <etj at geo-solutions.it> */ public class GeoBatchFtplet // extends DefaultFtplet implements Ftplet { private final static Logger LOGGER = LoggerFactory.getLogger(GeoBatchFtplet.class.getName()); private FtpStatistics ftpStats; public void init(FtpletContext ftpletContext) throws FtpException { this.ftpStats = ftpletContext.getFtpStatistics(); } public FtpletResult onConnect(FtpSession ftpSession) throws FtpException, IOException { logStatus(); return FtpletResult.DEFAULT; } private void logStatus() { LOGGER.info("FTP Stats: CONNECTIONS : {} / {} -- LOGINS : {} / {}", new Object[] { this.ftpStats.getCurrentConnectionNumber(), this.ftpStats.getTotalConnectionNumber(), this.ftpStats.getCurrentLoginNumber(), this.ftpStats.getTotalLoginNumber() }); } public FtpletResult onDisconnect(FtpSession session) throws FtpException, IOException { return null; } public FtpletResult beforeCommand(FtpSession session, FtpRequest request) throws FtpException, IOException { String command = request.getCommand().toUpperCase(); // if ("DELE".equals(command)) { // return onDeleteStart(session, request); // } else if ("STOR".equals(command)) { // return onUploadStart(session, request); // } else if ("RETR".equals(command)) { // return onDownloadStart(session, request); // } else if ("RMD".equals(command)) { return onRmdirStart(session, request); } else if ("MKD".equals(command)) { return onMkdirStart(session, request); // } else if ("APPE".equals(command)) { // return onAppendStart(session, request); // } else if ("STOU".equals(command)) { // return onUploadUniqueStart(session, request); } else if ("RNTO".equals(command)) { return onRenameStart(session, request); // } else if ("SITE".equals(command)) { // return onSite(session, request); } else { // TODO should we call a catch all? return null; } } public FtpletResult afterCommand(FtpSession session, FtpRequest request, FtpReply reply) throws FtpException, IOException { // the reply is ignored for these callbacks String command = request.getCommand().toUpperCase(); // if ("PASS".equals(command)) { // return onLogin(session, request); // } else if ("DELE".equals(command)) { // return onDeleteEnd(session, request); // } else if ("STOR".equals(command)) { return onUploadEnd(session, request, reply); // } else if ("RETR".equals(command)) { // return onDownloadEnd(session, request); // } else if ("RMD".equals(command)) { // return onRmdirEnd(session, request); // } else if ("MKD".equals(command)) { // return onMkdirEnd(session, request); } else if ("APPE".equals(command)) { return onAppendEnd(session, request, reply); // } else if ("STOU".equals(command)) { // return onUploadUniqueEnd(session, request); // } else if ("RNTO".equals(command)) { // return onRenameEnd(session, request); } else { // TODO should we call a catch all? return null; } } public FtpletResult onUploadEnd(FtpSession session, FtpRequest request, FtpReply reply) throws FtpException, IOException { if (reply.getCode() != FtpReply.REPLY_226_CLOSING_DATA_CONNECTION) { // There // has // been // an // error if (LOGGER.isInfoEnabled()) LOGGER.info("Upload of file '" + request.getArgument() + "' failed."); return FtpletResult.DEFAULT; } else { if (LOGGER.isInfoEnabled()) LOGGER.info("Upload of file '" + request.getArgument() + "' completed."); return fireGeoBatchFileAdd(session, request); } } public FtpletResult onAppendEnd(FtpSession session, FtpRequest request, FtpReply reply) throws FtpException, IOException { if (reply.getCode() != FtpReply.REPLY_226_CLOSING_DATA_CONNECTION) { if (LOGGER.isInfoEnabled()) LOGGER.info("Append of file '" + request.getArgument() + "' failed."); return FtpletResult.DEFAULT; } else { if (LOGGER.isInfoEnabled()) LOGGER.info("Append of file '" + request.getArgument() + "' completed."); return fireGeoBatchFileAdd(session, request); } } protected FtpletResult fireGeoBatchFileAdd(FtpSession session, FtpRequest request) throws FtpException, IOException { String userPath = session.getUser().getHomeDirectory(); String currDirPath = session.getFileSystemView().getWorkingDirectory().getAbsolutePath(); String filename = request.getArgument(); File dirFile = new File(userPath, currDirPath); File targetFile = new File(dirFile, filename); String flowid = FilenameUtils.getName(currDirPath); if (LOGGER.isInfoEnabled()) LOGGER.info("File upload/append finished: - session working dir: ''{}'' - file: ''{}''", new Object[] { currDirPath, filename }); Catalog catalog = CatalogHolder.getCatalog(); // CHECKME FIXME next call won't work: flowid are set as the file name, // not the config id // FileBasedFlowManager fm = catalog.getFlowManager(flowid, // FileBasedFlowManager.class); // CHECKME TODO this has to be made more // general FileBasedFlowManager fm = null; StringBuilder availFmSb = new StringBuilder("Available FlowManagers: "); for (FileBasedFlowManager fmloop : catalog.getFlowManagers(FileBasedFlowManager.class)) { availFmSb.append('(').append(fmloop.getId()).append(',').append(fmloop.getName()).append(')'); if (fmloop.getConfiguration().getId().equals(flowid)) { fm = fmloop; } } if (fm != null) { LOGGER.info("Firing FILEADDED event to {}", fm); fm.postEvent(new FileSystemEvent(targetFile, FileSystemEventType.FILE_ADDED)); } else { LOGGER.error("No FlowManager ''{}'' to notify about {} -- {}", new Object[] { flowid, targetFile, availFmSb }); } return FtpletResult.DEFAULT; } public void destroy() { // super.destroy(); } public FtpletResult onMkdirStart(FtpSession session, FtpRequest request) throws FtpException, IOException { session.write(new DefaultFtpReply(FtpReply.REPLY_550_REQUESTED_ACTION_NOT_TAKEN, "No permission.")); return FtpletResult.SKIP; } public FtpletResult onRmdirStart(FtpSession session, FtpRequest request) throws FtpException, IOException { session.write(new DefaultFtpReply(550, "No permission.")); return FtpletResult.SKIP; } public FtpletResult onRenameStart(FtpSession session, FtpRequest request) throws FtpException, IOException { session.write(new DefaultFtpReply(553, "No permission.")); return FtpletResult.SKIP; } }