Java tutorial
/* ############################################################################### # # # Copyright (C) 2011-2015 OpenMEAP, Inc. # # Credits to Jonathan Schang & Rob Thacher # # # # Released under the LGPLv3 # # # # OpenMEAP 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. # # # # OpenMEAP 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 OpenMEAP. If not, see <http://www.gnu.org/licenses/>. # # # ############################################################################### */ package com.openmeap.services; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.FileNameMap; import java.net.URLConnection; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.codec.net.URLCodec; import com.openmeap.thirdparty.org.json.me.JSONException; import com.openmeap.thirdparty.org.json.me.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import com.openmeap.constants.UrlParamConstants; import com.openmeap.digest.DigestException; import com.openmeap.json.JSONObjectBuilder; import com.openmeap.model.ModelManager; import com.openmeap.model.dto.ApplicationArchive; import com.openmeap.model.dto.ApplicationVersion; import com.openmeap.model.dto.ClusterNode; import com.openmeap.model.dto.GlobalSettings; import com.openmeap.protocol.ApplicationManagementService; import com.openmeap.protocol.WebServiceException; import com.openmeap.protocol.dto.Application; import com.openmeap.protocol.dto.ApplicationInstallation; import com.openmeap.protocol.dto.ConnectionOpenRequest; import com.openmeap.protocol.dto.ConnectionOpenResponse; import com.openmeap.protocol.dto.Error; import com.openmeap.protocol.dto.ErrorCode; import com.openmeap.protocol.dto.Result; import com.openmeap.protocol.dto.SLIC; import com.openmeap.util.AuthTokenProvider; import com.openmeap.util.GenericRuntimeException; import com.openmeap.util.Utils; public class ApplicationManagementServlet extends HttpServlet { private static final long serialVersionUID = -4989132152150822192L; private Logger logger = LoggerFactory.getLogger(ApplicationManagementServlet.class); private ModelManager modelManager = null; private WebApplicationContext context = null; @Override public void init() { context = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); modelManager = (ModelManager) context.getBean("modelManager"); } @Override public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Result result = new Result(); Error err = new Error(); String action = req.getParameter(UrlParamConstants.ACTION); if (action == null) action = ""; if (action.equals("connection-open-request")) { result = connectionOpenRequest(req); } else if (action.equals("archiveDownload")) { result = handleArchiveDownload(req, resp); if (result == null) { return; } } else { err.setCode(ErrorCode.MISSING_PARAMETER); err.setMessage("The \"action\" parameter is not recognized, missing, or empty."); result.setError(err); } try { JSONObjectBuilder builder = new JSONObjectBuilder(); resp.setContentType("text/javascript"); JSONObject jsonResult = builder.toJSON(result); resp.getOutputStream().write(jsonResult.toString().getBytes()); } catch (JSONException e) { throw new RuntimeException(e); } } private Result handleArchiveDownload(HttpServletRequest request, HttpServletResponse response) { Result res = new Result(); Error err = new Error(); res.setError(err); GlobalSettings settings = modelManager.getGlobalSettings(); Map properties = this.getServicesWebProperties(); String nodeKey = (String) properties.get("clusterNodeUrlPrefix"); ClusterNode clusterNode = settings.getClusterNode(nodeKey); if (nodeKey == null || clusterNode == null) { // TODO: create a configuration error code err.setCode(ErrorCode.UNDEFINED); err.setMessage("A configuration is missing. Please consult the error logs."); logger.error( "For each node in the cluster, the property or environment variable OPENMEAP_CLUSTER_NODE_URL_PREFIX must match the \"Service Url Prefix\" value configured in the administrative interface. This value is currently " + nodeKey + "."); return res; } String pathValidation = clusterNode.validateFileSystemStoragePathPrefix(); if (pathValidation != null) { err.setCode(ErrorCode.UNDEFINED); err.setMessage("A configuration is missing. Please consult the error logs."); logger.error( "There is an issue with the location at \"File-system Storage Prefix\". " + pathValidation); return res; } String hash = request.getParameter(UrlParamConstants.APPARCH_HASH); String hashAlg = request.getParameter(UrlParamConstants.APPARCH_HASH_ALG); String fileName = null; if (hash == null || hashAlg == null) { // look in the apps directory for the archive specified String appName = request.getParameter(UrlParamConstants.APP_NAME); String versionId = request.getParameter(UrlParamConstants.APP_VERSION); ApplicationVersion appVersion = modelManager.getModelService().findAppVersionByNameAndId(appName, versionId); if (appVersion == null) { String mesg = "The application version " + versionId + " was not found for application " + appName; err.setCode(ErrorCode.APPLICATION_VERSION_NOTFOUND); err.setMessage(mesg); logger.warn(mesg); return res; } String auth = request.getParameter(UrlParamConstants.AUTH_TOKEN); com.openmeap.model.dto.Application app = appVersion.getApplication(); try { if (auth == null || !AuthTokenProvider.validateAuthToken(app.getProxyAuthSalt(), auth)) { err.setCode(ErrorCode.AUTHENTICATION_FAILURE); err.setMessage("The \"auth\" token presented is not recognized, missing, or empty."); return res; } } catch (DigestException e) { throw new GenericRuntimeException(e); } hash = appVersion.getArchive().getHash(); hashAlg = appVersion.getArchive().getHashAlgorithm(); fileName = app.getName() + " - " + appVersion.getIdentifier(); } else { fileName = hashAlg + "-" + hash; } File file = ApplicationArchive.getFile(clusterNode.getFileSystemStoragePathPrefix(), hashAlg, hash); if (!file.exists()) { String mesg = "The application archive with " + hashAlg + " hash " + hash + " was not found."; // TODO: create an enumeration for this error err.setCode(ErrorCode.UNDEFINED); err.setMessage(mesg); logger.warn(mesg); return res; } try { FileNameMap fileNameMap = URLConnection.getFileNameMap(); String mimeType = fileNameMap.getContentTypeFor(file.toURL().toString()); response.setContentType(mimeType); response.setContentLength(Long.valueOf(file.length()).intValue()); URLCodec codec = new URLCodec(); response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + ".zip\";"); InputStream inputStream = null; OutputStream outputStream = null; try { inputStream = new BufferedInputStream(new FileInputStream(file)); outputStream = response.getOutputStream(); Utils.pipeInputStreamIntoOutputStream(inputStream, outputStream); } finally { if (inputStream != null) { inputStream.close(); } //if(outputStream!=null) {outputStream.close();} } response.flushBuffer(); } catch (FileNotFoundException e) { logger.error("Exception {}", e); } catch (IOException ioe) { logger.error("Exception {}", ioe); } return null; } /** * Pulls parameters out of the request and passes them to the ApplicationManagementPortType bean pulled from the WebApplicationContext * * @param req * @return */ public Result connectionOpenRequest(HttpServletRequest req) { WebApplicationContext context = WebApplicationContextUtils .getRequiredWebApplicationContext(getServletContext()); ConnectionOpenRequest request = createConnectionOpenRequest(req); Result result = new Result(); try { ConnectionOpenResponse response = ((ApplicationManagementService) context .getBean("applicationManagementService")).connectionOpen(request); result.setConnectionOpenResponse(response); } catch (WebServiceException wse) { Error err = new Error(); err.setCode(wse.getType().asErrorCode()); err.setMessage(wse.getMessage()); result.setError(err); } return result; } private ConnectionOpenRequest createConnectionOpenRequest(HttpServletRequest req) { ConnectionOpenRequest request = new ConnectionOpenRequest(); request.setApplication(new Application()); Application app = request.getApplication(); app.setVersionId(req.getParameter(UrlParamConstants.APP_VERSION)); app.setName(req.getParameter(UrlParamConstants.APP_NAME)); app.setHashValue(req.getParameter(UrlParamConstants.APPARCH_HASH)); app.setInstallation(new ApplicationInstallation()); app.getInstallation().setUuid(req.getParameter(UrlParamConstants.DEVICE_UUID)); request.setSlic(new SLIC()); SLIC slic = request.getSlic(); slic.setVersionId(req.getParameter(UrlParamConstants.SLIC_VERSION)); return request; } public Map getServicesWebProperties() { return (Map) context.getBean("openmeapServicesWebPropertiesMap"); } // ACCESSORS public void setModelManager(ModelManager manager) { modelManager = manager; } public ModelManager getModelManager() { return modelManager; } }