2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
20 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 package org.onap.aai.restcore;
24 import java.io.UnsupportedEncodingException;
26 import java.util.ArrayList;
27 import java.util.List;
29 import javax.ws.rs.core.HttpHeaders;
30 import javax.ws.rs.core.MediaType;
31 import javax.ws.rs.core.Response;
32 import javax.ws.rs.core.UriInfo;
34 import org.onap.aai.db.props.AAIProperties;
35 import org.onap.aai.dbmap.DBConnectionType;
36 import org.onap.aai.exceptions.AAIException;
37 import org.onap.aai.introspection.Introspector;
38 import org.onap.aai.introspection.Loader;
39 import org.onap.aai.introspection.tools.CreateUUID;
40 import org.onap.aai.introspection.tools.DefaultFields;
41 import org.onap.aai.introspection.tools.InjectKeysFromURI;
42 import org.onap.aai.introspection.tools.IntrospectorValidator;
43 import org.onap.aai.introspection.tools.Issue;
44 import org.onap.aai.introspection.tools.RemoveNonVisibleProperty;
45 import org.onap.aai.logging.ErrorLogHelper;
46 import org.onap.aai.logging.LoggingContext;
47 import org.onap.aai.util.AAIConfig;
48 import org.onap.aai.util.FormatDate;
50 import com.att.eelf.configuration.EELFLogger;
51 import com.att.eelf.configuration.EELFManager;
52 import com.google.common.base.Joiner;
56 * Base class for AAI REST API classes.
57 * Provides method to validate header information
58 * TODO should authenticate caller and authorize them for the API they are calling
59 * TODO should store the transaction
63 public class RESTAPI {
65 private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(RESTAPI.class);
67 protected final String COMPONENT = "aairest";
73 GET, PUT, POST, DELETE
77 * Gets the from app id.
79 * @param headers the headers
80 * @param logline the logline
81 * @return the from app id
82 * @throws AAIException the AAI exception
84 protected String getFromAppId(HttpHeaders headers) throws AAIException {
85 String fromAppId = null;
86 if (headers != null) {
87 List<String> fromAppIdHeader = headers.getRequestHeader("X-FromAppId");
88 if (fromAppIdHeader != null) {
89 for (String fromAppIdValue : fromAppIdHeader) {
90 fromAppId = fromAppIdValue;
95 if (fromAppId == null) {
96 throw new AAIException("AAI_4009");
99 LoggingContext.partnerName(fromAppId);
107 * @param headers the headers
108 * @param logline the logline
109 * @return the trans id
110 * @throws AAIException the AAI exception
112 protected String getTransId(HttpHeaders headers) throws AAIException {
113 String transId = null;
114 if (headers != null) {
115 List<String> transIdHeader = headers.getRequestHeader("X-TransactionId");
116 if (transIdHeader != null) {
117 for (String transIdValue : transIdHeader) {
118 transId = transIdValue;
123 if (transId == null) {
124 throw new AAIException("AAI_4010");
127 LoggingContext.requestId(transId);
138 protected String genDate() {
139 FormatDate fd = new FormatDate( "YYMMdd-HH:mm:ss:SSS");
141 return fd.getDateTime();
145 * Gets the media type.
147 * @param mediaTypeList the media type list
148 * @return the media type
150 protected String getMediaType(List <MediaType> mediaTypeList) {
151 String mediaType = MediaType.APPLICATION_JSON; // json is the default
152 for (MediaType mt : mediaTypeList) {
153 if (MediaType.APPLICATION_XML_TYPE.isCompatible(mt)) {
154 mediaType = MediaType.APPLICATION_XML;
161 /* ----------helpers for common consumer actions ----------- */
166 * @param depthParam the depth param
168 * @throws AAIException the AAI exception
170 protected int setDepth(String depthParam) throws AAIException {
171 int depth = AAIProperties.MAXIMUM_DEPTH; //default
172 if (depthParam != null && depthParam.length() > 0 && !depthParam.equals("all")){
174 depth = Integer.valueOf(depthParam);
175 } catch (Exception e) {
176 throw new AAIException("AAI_4016");
183 * Consumer exception response generator.
185 * @param headers the headers
186 * @param info the info
187 * @param templateAction the template action
189 * @return the response
191 protected Response consumerExceptionResponseGenerator(HttpHeaders headers, UriInfo info, HttpMethod templateAction, AAIException e) {
192 ArrayList<String> templateVars = new ArrayList<String>();
193 templateVars.add(templateAction.toString()); //GET, PUT, etc
194 templateVars.add(info.getPath().toString());
195 templateVars.addAll(e.getTemplateVars());
198 .status(e.getErrorObject().getHTTPResponseCode())
199 .entity(ErrorLogHelper.getRESTAPIErrorResponseWithLogging(headers.getAcceptableMediaTypes(), e, templateVars))
204 * Validate introspector.
207 * @param loader the loader
209 * @param validateRequired the validate required
210 * @throws AAIException the AAI exception
211 * @throws UnsupportedEncodingException the unsupported encoding exception
213 protected void validateIntrospector(Introspector obj, Loader loader, URI uri, HttpMethod method) throws AAIException, UnsupportedEncodingException {
215 int maximumDepth = AAIProperties.MAXIMUM_DEPTH;
216 boolean validateRequired = true;
217 if (method.equals(HttpMethod.MERGE_PATCH)) {
218 validateRequired = false;
221 IntrospectorValidator validator = new IntrospectorValidator.Builder()
222 .validateRequired(validateRequired)
223 .restrictDepth(maximumDepth)
224 .addResolver(new RemoveNonVisibleProperty())
225 .addResolver(new CreateUUID())
226 .addResolver(new DefaultFields())
227 .addResolver(new InjectKeysFromURI(loader, uri))
229 boolean result = validator.validate(obj);
231 result = validator.resolveIssues();
234 List<String> messages = new ArrayList<>();
235 for (Issue issue : validator.getIssues()) {
236 if (!issue.isResolved()) {
237 messages.add(issue.getDetail());
240 String errors = Joiner.on(",").join(messages);
241 throw new AAIException("AAI_3000", errors);
243 //check that key in payload and key in request uri are the same
244 String objURI = obj.getURI();
245 //if requested object is a parent objURI will have a leading slash the input uri will lack
246 //this adds that leading slash for the comparison
247 String testURI = "/" + uri.getRawPath();
248 if (!testURI.endsWith(objURI)) {
249 throw new AAIException("AAI_3000", "uri and payload keys don't match");
253 protected DBConnectionType determineConnectionType(String fromAppId, String realTime) {
254 DBConnectionType type = DBConnectionType.REALTIME;
255 boolean isRealTimeClient = AAIConfig.get("aai.realtime.clients", "").contains(fromAppId);
256 if (isRealTimeClient || realTime != null) {
257 type = DBConnectionType.REALTIME;
259 type = DBConnectionType.CACHED;
266 * Gets the input media type.
268 * @param mediaType the media type
269 * @return the input media type
271 protected String getInputMediaType(MediaType mediaType) {
272 String result = mediaType.getType() + "/" + mediaType.getSubtype();