AT&T 2.0.19 Code drop, stage 3
[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 isGet;
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                 isGet = meth.compareTo(HttpMethods.GET) == 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 void add(HttpCode<TRANS,?> code, Class<?> cls, String version, String ... others) {
60 //              code.match = match;
61 //              content.add(code, cls, version, others);
62 //      }
63 //
64         public HttpCode<TRANS,?> getCode(TRANS trans, HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
65                 // Type is associated with Accept for GET (since it is what is being returned
66                 // We associate the rest with ContentType.
67                 // FYI, thought about this a long time before implementing this way.
68                 String compare;
69 //              String special[]; // todo, expose Charset (in special) to outside
70                 if(isGet) {
71                         compare = req.getHeader("Accept"); // Accept is used for read, as we want to agree on what caller is ready to handle
72                 } else {
73                         compare = req.getContentType(); // Content type used to declare what data is being created, updated or deleted (might be used for key)
74                 }
75
76                 Pair<String, Pair<HttpCode<TRANS, ?>, List<Pair<String, Object>>>> hl = content.prep(trans, compare);
77                 if(hl==null) {
78                         resp.setStatus(406); // NOT_ACCEPTABLE
79                 } else {
80                         if(isGet) { // Set Content Type to expected content
81                                 if("*".equals(hl.x) || "*/*".equals(hl.x)) {// if wild-card, then choose first kind of type
82                                         resp.setContentType(content.first());
83                                 } else {
84                                         resp.setContentType(hl.x);
85                                 }
86                         }
87                         return hl.y.x;
88                 }
89                 return null;
90         }
91         
92         public Route<TRANS> matches(String method, String path) {
93                 return meth.name().equalsIgnoreCase(method) && match.match(path)?this:null;
94         }
95         
96         public TimeTaken start(Trans trans, String auditText, HttpCode<TRANS,?> code, String type) {
97                 StringBuilder sb = new StringBuilder(auditText);
98                 sb.append(", ");
99                 sb.append(code.desc());
100                 sb.append(", Content: ");
101                 sb.append(type);
102                 return trans.start(sb.toString(), Env.SUB);
103         }
104
105         // Package on purpose.. for "find/Create" routes only
106         boolean resolvesTo(HttpMethods hm, String p) {
107                 return(path.equals(p) && hm.equals(meth));
108         }
109         
110         public String toString() {
111                 return auditText + ' ' + content; 
112         }
113
114         public String report(HttpCode<TRANS, ?> code) {
115                 StringBuilder sb = new StringBuilder();
116                 sb.append(auditText);
117                 sb.append(' ');
118                 content.relatedTo(code, sb);
119                 return sb.toString();
120         }
121
122         public RouteReport api() {
123                 RouteReport tr = new RouteReport();
124                 tr.meth = meth;
125                 tr.path = path;
126                 content.api(tr);
127                 return tr;
128         }
129
130
131         /**
132          * contentRelatedTo (For reporting) list routes that will end up at a specific Code
133          * @return
134          */
135         public String contentRelatedTo(HttpCode<TRANS, ?> code) {
136                 StringBuilder sb = new StringBuilder(path);
137                 sb.append(' ');
138                 content.relatedTo(code, sb);
139                 return sb.toString();
140         }
141 }