[DMAAP-48] Initial code import
[dmaap/datarouter.git] / Subscriber / src / SubscriberServlet.java
1 /*******************************************************************************
2  * ============LICENSE_START==================================================
3  * * org.onap.dmaap
4  * * ===========================================================================
5  * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6  * * ===========================================================================
7  * * Licensed under the Apache License, Version 2.0 (the "License");
8  * * you may not use this file except in compliance with the License.
9  * * You may obtain a copy of the License at
10  * * 
11  *  *      http://www.apache.org/licenses/LICENSE-2.0
12  * * 
13  *  * Unless required by applicable law or agreed to in writing, software
14  * * distributed under the License is distributed on an "AS IS" BASIS,
15  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * * See the License for the specific language governing permissions and
17  * * limitations under the License.
18  * * ============LICENSE_END====================================================
19  * *
20  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
21  * *
22  ******************************************************************************/
23
24 import java.io.File;
25 import java.io.FileOutputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.OutputStream;
29 import java.net.URLEncoder;
30
31 import javax.servlet.ServletConfig;
32 import javax.servlet.ServletException;
33 import javax.servlet.http.HttpServlet;
34 import javax.servlet.http.HttpServletRequest;
35 import javax.servlet.http.HttpServletResponse;
36
37 import org.apache.commons.codec.binary.Base64;
38 import org.apache.log4j.Logger;
39
40 /**
41  *      Example stand alone subscriber servlet with Authorization header checking
42  */
43 public class SubscriberServlet extends HttpServlet      {
44         private static Logger logger = Logger.getLogger("com.att.datarouter.pubsub.ssasubscribe.SubscriberServlet");
45         private String Login = "LOGIN";
46         private String Password = "PASSWORD";
47         private String OutputDirectory = "/root/sub/received";
48
49         private String auth;
50
51         private static String gp(ServletConfig config, String param, String deflt) {
52                 param = config.getInitParameter(param);
53                 if (param == null || param.length() == 0) {
54                         param = deflt;
55                 }
56                 return(param);
57         }
58         /**
59          *      Configure this subscriberservlet.  Configuration parameters from config.getInitParameter() are:
60          *      <ul>
61          *      <li>Login - The login expected in the Authorization header (default "LOGIN").
62          *      <li>Password - The password expected in the Authorization header (default "PASSWORD").
63          *      <li>OutputDirectory - The directory where files are placed (default "received").
64          *      </ul>
65          */
66         public void init(ServletConfig config) throws ServletException {
67                 Login = gp(config, "Login", Login);
68                 Password = gp(config, "Password", Password);
69                 OutputDirectory = gp(config, "OutputDirectory", OutputDirectory);
70                 (new File(OutputDirectory)).mkdirs();
71                 auth = "Basic " + Base64.encodeBase64String((Login + ":" + Password).getBytes());
72         }
73         /**
74          *      Invoke common(req, resp, false).
75          */
76         protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
77                 common(req, resp, false);
78         }
79         /**
80          *      Invoke common(req, resp, true).
81          */
82         protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
83                 common(req, resp, true);
84         }
85         /**
86          *      Process a PUT or DELETE request.
87          *      <ol>
88          *      <li>Verify that the request contains an Authorization header
89          *      or else UNAUTHORIZED.
90          *      <li>Verify that the Authorization header matches the configured
91          *      Login and Password or else FORBIDDEN.
92          *      <li>If the request is PUT, store the message body as a file
93          *      in the configured OutputDirectory directory protecting against
94          *      evil characters in the received FileID.  The file is created
95          *      initially with its name prefixed with a ".", and once it is complete, it is
96          *      renamed to remove the leading "." character.
97          *      <li>If the request is DELETE, instead delete the file (if it exists) from the configured OutputDirectory directory.
98          *      <li>Respond with NO_CONTENT.
99          *      </ol>
100          */
101         protected void common(HttpServletRequest req, HttpServletResponse resp, boolean isdelete) throws ServletException, IOException {
102                 String ah = req.getHeader("Authorization");
103                 if (ah == null) {
104                         logger.info("Rejecting request with no Authorization header from " + req.getRemoteAddr() + ": " + req.getPathInfo());
105                         resp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
106                         return;
107                 }
108                 if (!auth.equals(ah)) {
109                         logger.info("Rejecting request with incorrect Authorization header from " + req.getRemoteAddr() + ": " + req.getPathInfo());
110                         resp.sendError(HttpServletResponse.SC_FORBIDDEN);
111                         return;
112                 }
113                 String fileid = req.getPathInfo();
114                 fileid = fileid.substring(fileid.lastIndexOf('/') + 1);
115                 String qs = req.getQueryString();
116                 if (qs != null) {
117                         fileid = fileid + "?" + qs;
118                 }
119                 String publishid = req.getHeader("X-ATT-DR-PUBLISH-ID");
120                 String filename = URLEncoder.encode(fileid, "UTF-8").replaceAll("^\\.", "%2E").replaceAll("\\*", "%2A");
121                 String finalname = OutputDirectory + "/" + filename;
122                 String tmpname = OutputDirectory + "/." + filename;
123                 try {
124                         if (isdelete) {
125                                 (new File(finalname)).delete();
126                                 logger.info("Received delete for file id " + fileid + " from " + req.getRemoteAddr() + " publish id " + publishid + " as " + finalname);
127                         } else {
128                                 InputStream is = req.getInputStream();
129                                 OutputStream os = new FileOutputStream(tmpname);
130                                 byte[] buf = new byte[65536];
131                                 int i;
132                                 while ((i = is.read(buf)) > 0) {
133                                         os.write(buf, 0, i);
134                                 }
135                                 is.close();
136                                 os.close();
137                                 (new File(tmpname)).renameTo(new File(finalname));
138                                 logger.info("Received file id " + fileid + " from " + req.getRemoteAddr() + " publish id " + publishid + " as " + finalname);
139                                 resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
140                                 logger.info("Received file id " + fileid + " from " + req.getRemoteAddr() + " publish id " + publishid + " as " + finalname);
141                         }
142                         resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
143                 } catch (IOException ioe) {
144                         (new File(tmpname)).delete();
145                         logger.info("Failure to save file " + finalname + " from " + req.getRemoteAddr() + ": " + req.getPathInfo(), ioe);
146                         throw ioe;
147                 }
148         }
149 }