f8c5ae19da53b1d6b1a829478bc396c4afd65470
[aaf/authz.git] / auth / auth-core / src / main / java / org / onap / aaf / auth / rserv / Route.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
4  * ===========================================================================
5  * Copyright (c) 2018 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  */
21
22 package org.onap.aaf.auth.rserv;
23
24 import java.io.IOException;
25 import java.util.List;
26
27 import javax.servlet.ServletException;
28 import javax.servlet.http.HttpServletRequest;
29 import javax.servlet.http.HttpServletResponse;
30
31 import org.onap.aaf.misc.env.Env;
32 import org.onap.aaf.misc.env.TimeTaken;
33 import org.onap.aaf.misc.env.Trans;
34
35 public class Route<TRANS extends Trans> {
36     public final String auditText;
37     public final HttpMethods meth;
38     public final String path;
39
40     private Match match;
41     // package on purpose
42     private final TypedCode<TRANS> content;
43     private final boolean isContentType;
44
45     public Route(HttpMethods meth, String path) {
46         this.path = path;
47         auditText = meth.name() + ' ' + path;
48         this.meth = meth; // Note: Using Spark def for now.
49         isContentType = meth.compareTo(HttpMethods.GET) == 0 || meth.compareTo(HttpMethods.DELETE)==0;
50         match = new Match(path);
51         content = new TypedCode<TRANS>();
52     }
53
54     public void add(HttpCode<TRANS,?> code, String ... others) {
55         code.match = match;
56         content.add(code, others);
57     }
58
59     public HttpCode<TRANS,?> getCode(TRANS trans, HttpServletRequest req, HttpServletResponse resp) {
60         // Type is associated with Accept for GET (since it is what is being returned
61         // We associate the rest with ContentType.
62         // FYI, thought about this a long time before implementing this way.
63         String compare;
64         if (isContentType) {
65             compare = req.getHeader("Accept"); // Accept is used for read, as we want to agree on what caller is ready to handle
66         } else {
67             compare = req.getContentType(); // Content type used to declare what data is being created, updated or deleted (might be used for key)
68         }
69
70         Pair<String, Pair<HttpCode<TRANS, ?>, List<Pair<String, Object>>>> hl = content.prep(trans, compare);
71         if (hl==null) {
72             resp.setStatus(406); // NOT_ACCEPTABLE
73         } else {
74             if (isContentType) { // Set Content Type to expected content
75                 if ("*".equals(hl.x) || "*/*".equals(hl.x)) {// if wild-card, then choose first kind of type
76                     resp.setContentType(content.first());
77                 } else {
78                     resp.setContentType(hl.x);
79                 }
80             }
81             return hl.y.x;
82         }
83         return null;
84     }
85
86     public Route<TRANS> matches(String method, String path) {
87         return meth.name().equalsIgnoreCase(method) && match.match(path)?this:null;
88     }
89
90     public TimeTaken start(Trans trans, String auditText, HttpCode<TRANS,?> code, String type) {
91         StringBuilder sb = new StringBuilder(auditText);
92         sb.append(", ");
93         sb.append(code.desc());
94         sb.append(", Content: ");
95         sb.append(type);
96         return trans.start(sb.toString(), Env.SUB);
97     }
98
99     // Package on purpose.. for "find/Create" routes only
100     boolean resolvesTo(HttpMethods hm, String p) {
101         return(path.equals(p) && hm.equals(meth));
102     }
103
104     public String toString() {
105         return auditText + ' ' + content;
106     }
107
108     public String report(HttpCode<TRANS, ?> code) {
109         StringBuilder sb = new StringBuilder();
110         sb.append(auditText);
111         sb.append(' ');
112         content.relatedTo(code, sb);
113         return sb.toString();
114     }
115
116     public RouteReport api() {
117         RouteReport tr = new RouteReport();
118         tr.meth = meth;
119         tr.path = path;
120         content.api(tr);
121         return tr;
122     }
123
124
125     /**
126      * contentRelatedTo (For reporting) list routes that will end up at a specific Code
127      * @return
128      */
129     public String contentRelatedTo(HttpCode<TRANS, ?> code) {
130         StringBuilder sb = new StringBuilder(path);
131         sb.append(' ');
132         content.relatedTo(code, sb);
133         return sb.toString();
134     }
135 }