<commit_before>/**
 *  Copyright (C) 2011 Cloud.com.  All rights reserved.
 *
 * This software is licensed under the GNU General Public License v3 or later. 
 *
 * It 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 3 of the License, or 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.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
package com.cloud.agent.vmdata;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.File;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ejb.Local;
import javax.naming.ConfigurationException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Handler;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.handler.DefaultHandler;
import org.mortbay.jetty.handler.HandlerList;
import org.mortbay.jetty.handler.ResourceHandler;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.ServletHolder;
import org.mortbay.thread.QueuedThreadPool;

import com.cloud.agent.api.Answer;
import com.cloud.agent.api.routing.VmDataCommand;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.network.Networks.TrafficType;
import com.cloud.storage.JavaStorageLayer;
import com.cloud.storage.StorageLayer;
import com.cloud.utils.net.NetUtils;

/**
 * Serves vm data using embedded Jetty server
 *
 */
@Local (value={VmDataServer.class})
public class JettyVmDataServer implements VmDataServer {
    private static final Logger s_logger = Logger.getLogger(JettyVmDataServer.class);
    
    public static final String USER_DATA = "user-data";
    public static final String META_DATA = "meta-data";
    protected String _vmDataDir;
    protected Server _jetty;
    protected String _hostIp;
    protected Map<String, String> _ipVmMap = new HashMap<String, String>();
    protected StorageLayer _fs = new JavaStorageLayer();
    
    public class VmDataServlet extends HttpServlet {

        private static final long serialVersionUID = -1640031398971742349L;
        
        JettyVmDataServer _vmDataServer;
        String _dataType; //userdata or meta-data
       
        
        public VmDataServlet(JettyVmDataServer dataServer, String dataType) {
            this._vmDataServer = dataServer;
            this._dataType = dataType;
        }
        
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            int port = req.getServerPort();
            if (port != 80 && port != 8000) {
                resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Request not understood");
                return;
            }
            if (_dataType.equalsIgnoreCase(USER_DATA)) {
                handleUserData(req, resp);
            } else if (_dataType.equalsIgnoreCase(META_DATA)) {
                handleMetaData(req, resp);
            }
        }
        
        protected void handleUserData(HttpServletRequest req, HttpServletResponse resp) 
                throws ServletException, IOException {
            String requester = req.getRemoteAddr();
            resp.setContentType("text/html");
            resp.setStatus(HttpServletResponse.SC_OK);
            String userData = _vmDataServer.getVmDataItem(requester, USER_DATA);
            if (userData != null){
                resp.getWriter().println(userData);
            } else {
                resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
                resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Request not found");
            }
            
        }
        
        protected void handleMetaData(HttpServletRequest req, HttpServletResponse resp) 
                throws ServletException, IOException {
            String metadataItem = req.getPathInfo();
            String requester = req.getRemoteAddr();
            resp.setContentType("text/html");
            resp.setStatus(HttpServletResponse.SC_OK);
            String metaData = _vmDataServer.getVmDataItem(requester, metadataItem);
            if (metaData != null) {
                resp.getWriter().println(_vmDataServer.getVmDataItem(requester, metadataItem));
            } else {
                resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Request not found");
            }
        }
        
    }
    
    @Override
    public boolean configure(String name, Map<String, Object> params)
            throws ConfigurationException {
        boolean success = true;
        try {
            int vmDataPort = 80;
            int fileservingPort = 8000;
            _vmDataDir = (String)params.get("vm.data.dir");
            String port = (String) params.get("vm.data.port");
            if (port != null) {
                vmDataPort = Integer.parseInt(port);
            }
            port = (String) params.get("file.server.port");<commit_msg>bug 10212: Finally, user data works. Don't return newline to them status 10212: resolved, fixed<commit_after>/**
 *  Copyright (C) 2011 Cloud.com.  All rights reserved.
 *
 * This software is licensed under the GNU General Public License v3 or later. 
 *
 * It 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 3 of the License, or 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.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
package com.cloud.agent.vmdata;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.File;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ejb.Local;
import javax.naming.ConfigurationException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Handler;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.handler.DefaultHandler;
import org.mortbay.jetty.handler.HandlerList;
import org.mortbay.jetty.handler.ResourceHandler;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.ServletHolder;
import org.mortbay.thread.QueuedThreadPool;

import com.cloud.agent.api.Answer;
import com.cloud.agent.api.routing.VmDataCommand;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.network.Networks.TrafficType;
import com.cloud.storage.JavaStorageLayer;
import com.cloud.storage.StorageLayer;
import com.cloud.utils.net.NetUtils;

/**
 * Serves vm data using embedded Jetty server
 *
 */
@Local (value={VmDataServer.class})
public class JettyVmDataServer implements VmDataServer {
    private static final Logger s_logger = Logger.getLogger(JettyVmDataServer.class);
    
    public static final String USER_DATA = "user-data";
    public static final String META_DATA = "meta-data";
    protected String _vmDataDir;
    protected Server _jetty;
    protected String _hostIp;
    protected Map<String, String> _ipVmMap = new HashMap<String, String>();
    protected StorageLayer _fs = new JavaStorageLayer();
    
    public class VmDataServlet extends HttpServlet {

        private static final long serialVersionUID = -1640031398971742349L;
        
        JettyVmDataServer _vmDataServer;
        String _dataType; //userdata or meta-data
       
        
        public VmDataServlet(JettyVmDataServer dataServer, String dataType) {
            this._vmDataServer = dataServer;
            this._dataType = dataType;
        }
        
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            int port = req.getServerPort();
            if (port != 80 && port != 8000) {
                resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Request not understood");
                return;
            }
            if (_dataType.equalsIgnoreCase(USER_DATA)) {
                handleUserData(req, resp);
            } else if (_dataType.equalsIgnoreCase(META_DATA)) {
                handleMetaData(req, resp);
            }
        }
        
        protected void handleUserData(HttpServletRequest req, HttpServletResponse resp) 
                throws ServletException, IOException {
            String requester = req.getRemoteAddr();
            resp.setContentType("text/html");
            resp.setStatus(HttpServletResponse.SC_OK);
            String userData = _vmDataServer.getVmDataItem(requester, USER_DATA);
            if (userData != null){
                resp.getWriter().print(userData);
            } else {
                resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
                resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Request not found");
            }
            
        }
        
        protected void handleMetaData(HttpServletRequest req, HttpServletResponse resp) 
                throws ServletException, IOException {
            String metadataItem = req.getPathInfo();
            String requester = req.getRemoteAddr();
            resp.setContentType("text/html");
            resp.setStatus(HttpServletResponse.SC_OK);
            String metaData = _vmDataServer.getVmDataItem(requester, metadataItem);
            if (metaData != null) {
                resp.getWriter().print(_vmDataServer.getVmDataItem(requester, metadataItem));
            } else {
                resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Request not found");
            }
        }
        
    }
    
    @Override
    public boolean configure(String name, Map<String, Object> params)
            throws ConfigurationException {
        boolean success = true;
        try {
            int vmDataPort = 80;
            int fileservingPort = 8000;
            _vmDataDir = (String)params.get("vm.data.dir");
            String port = (String) params.get("vm.data.port");
            if (port != null) {
                vmDataPort = Integer.parseInt(port);
            }
            port = (String) params.get("file.server.port");
{'fraction_non_alphanumeric': 0.08730428863172227, 'fraction_numerical': 0.007658270932607215, 'mean_word_length': 2.8258463541666665, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5103634', 'n_tokens_mistral': 3289, 'n_tokens_neox': 3169, 'n_words': 815}