X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=otf-service-api%2Fsrc%2Fmain%2Fjava%2Forg%2Foran%2Fotf%2Fapi%2FUtilities.java;fp=otf-service-api%2Fsrc%2Fmain%2Fjava%2Forg%2Foran%2Fotf%2Fapi%2FUtilities.java;h=1279688a03d787e8e51294a554ab3a22dba7a46c;hb=14f6f95c84a4a1fa8774190db4a03fd0214ec55f;hp=0000000000000000000000000000000000000000;hpb=f49bd1efeaaddd4891c1f329b18d8cfb28b3e75b;p=it%2Fotf.git diff --git a/otf-service-api/src/main/java/org/oran/otf/api/Utilities.java b/otf-service-api/src/main/java/org/oran/otf/api/Utilities.java new file mode 100644 index 0000000..1279688 --- /dev/null +++ b/otf-service-api/src/main/java/org/oran/otf/api/Utilities.java @@ -0,0 +1,394 @@ +/* Copyright (c) 2019 AT&T Intellectual Property. # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +##############################################################################*/ + + +package org.oran.otf.api; + +import org.oran.otf.common.model.User; +import org.oran.otf.common.model.local.OTFApiResponse; +import org.oran.otf.common.repository.UserRepository; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Strings; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonParser; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Arrays; +import java.util.Base64; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import org.bson.types.ObjectId; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.mongodb.repository.MongoRepository; + +public class Utilities { + + public static JsonObject parseJson(String str) { + try { + return new JsonParser().parse(str).getAsJsonObject(); + } catch (JsonParseException jpe) { + logger.error("Cannot parse string as Json."); + return null; + } + } + + public static class Http { + public static class BuildResponse { + public static Response badRequest() { + return Response.status(400).build(); + } + + public static Response badRequestWithMessage(String msg) { + return Response.status(400) + .type(MediaType.APPLICATION_JSON) + .entity(new OTFApiResponse(400, msg)) + .build(); + } + + public static Response internalServerError() { + return Response.status(500).build(); + } + + public static Response internalServerErrorWithMessage(String msg) { + return Response.status(500) + .type(MediaType.APPLICATION_JSON) + .entity(new OTFApiResponse(500, msg)) + .build(); + } + + public static Response unauthorized() { + return Response.status(401).build(); + } + + public static Response unauthorizedWithMessage(String msg) { + return Response.status(401) + .type(MediaType.APPLICATION_JSON) + .entity(new OTFApiResponse(401, msg)) + .build(); + } + } + + public static HttpResponse httpPostJsonUsingAAF(String url, String body) throws Exception { + HttpResponse response = null; + + String aafCredentialsDecoded = + System.getenv("AAF_ID") + ":" + System.getenv("AAF_MECH_PASSWORD"); + + HttpPost post = new HttpPost(url); + post.setHeader("Content-Type", MediaType.APPLICATION_JSON); + post.setHeader( + "Authorization", + "Basic " + Base64.getEncoder().encodeToString(aafCredentialsDecoded.getBytes())); + post.setEntity(new StringEntity(body)); + + HttpClient client = + HttpClientBuilder.create() + .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE) + .build(); + response = client.execute(post); + + // logger.info(String.format("[POST:%s]\n %s", url, body)); + + return response; + } + + public static HttpResponse httpDeleteAAF(String url) { + HttpResponse response = null; + + try { + String aafCredentialsDecoded = + System.getenv("AAF_ID") + ":" + System.getenv("AAF_MECH_PASSWORD"); + + HttpDelete delete = new HttpDelete(url); + delete.setHeader( + "Authorization", + "Basic " + Base64.getEncoder().encodeToString(aafCredentialsDecoded.getBytes())); + HttpClient client = + HttpClientBuilder.create() + .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE) + .build(); + response = client.execute(delete); + + // logger.info(String.format("[DELETE:%s]\n", url)); + } catch (Exception e) { + e.printStackTrace(); + } + + return response; + } + + public static HttpResponse httpPostXmlUsingAAF(String url, String body) { + HttpResponse response = null; + + try { + String aafCredentialsDecoded = + System.getenv("AAF_ID") + ":" + System.getenv("AAF_MECH_PASSWORD"); + + HttpPost post = new HttpPost(url); + post.setHeader("Content-Type", MediaType.APPLICATION_JSON); + post.setHeader( + "Authorization", + "Basic " + Base64.getEncoder().encodeToString(aafCredentialsDecoded.getBytes())); + post.setEntity(new StringEntity(body)); + + List urlParameters = Arrays.asList(new BasicNameValuePair("xml", body)); + post.setEntity(new UrlEncodedFormEntity(urlParameters)); + + HttpClient client = HttpClientBuilder.create().build(); + response = client.execute(post); + + logger.info(String.format("[POST:%s]\n %s", url, body)); + } catch (Exception e) { + e.printStackTrace(); + } + + return response; + } + + public static HttpResponse httpGetUsingAAF(String url) { + HttpResponse response = null; + + try { + String aafCredentialsDecoded = + System.getenv("AAF_ID") + ":" + System.getenv("AAF_MECH_PASSWORD"); + + HttpGet get = new HttpGet(url); + get.setHeader("Content-Type", "application/json"); + get.setHeader( + "Authorization", + "Basic " + Base64.getEncoder().encodeToString(aafCredentialsDecoded.getBytes())); + + HttpClient client = + HttpClientBuilder.create() + .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE) + .build(); + response = client.execute(get); + + logger.info(String.format("[GET:%s]", url)); + } catch (Exception e) { + e.printStackTrace(); + } + + return response; + } + } + + public static class Camunda { + + public static boolean isCamundaOnline() { + final String healthUrl = + String.format( + "%s:%s/%s", + System.getenv("otf.camunda.host"), + System.getenv("otf.camunda.port"), + System.getenv("otf.camunda.uri.health")); + + HttpResponse res = Utilities.Http.httpGetUsingAAF(healthUrl); + return res != null && res.getStatusLine().getStatusCode() == 200; + } + + public static JsonObject processInstanceStatus(String executionId) { + // Read necessary environment variables - Avoiding using Spring dependencies (@Value) + String host = System.getenv("otf.camunda.host"); + String path = System.getenv("otf.camunda.uri.process-instance-completion-check"); + int port = Utilities.TryGetEnvironmentVariable("otf.camunda.port"); + + if (!Utilities.isHostValid(host)) { + logger.error("Host (%s) must use either the http or https protocol.", host); + return null; + } + + if (!Utilities.isPortValid(port)) { + logger.error( + "Invalid port (%s) specified as environment variable 'otf.camunda.port'.", + System.getenv("otf.camunda.port")); + return null; + } + try { + String getUrl = String.format("%s:%s/%s/%s", host, port, path, executionId); + HttpResponse response = Utilities.Http.httpGetUsingAAF(getUrl); + HttpEntity entity = response.getEntity(); + String result = EntityUtils.toString(entity); + + return parseJson(result); + } catch (IOException ioe) { + Utilities.printStackTrace(ioe, Utilities.LogLevel.ERROR); + logger.error("Cannot convert http entity to String."); + } catch (Exception e) { + Utilities.printStackTrace(e, Utilities.LogLevel.ERROR); + } + // conversion was unsuccessful + return null; + } + } + + private static final Logger logger = LoggerFactory.getLogger(Utilities.class); + + public static void printStackTrace(Exception exception, LogLevel logLevel) { + String stackTrace = getStackTrace(exception); + + switch (logLevel) { + case INFO: + logger.info(stackTrace); + break; + case WARN: + logger.warn(stackTrace); + break; + case DEBUG: + logger.debug(stackTrace); + break; + case ERROR: + logger.error(stackTrace); + break; + } + } + + public static int TryGetEnvironmentVariable(String variable) { + String value = System.getenv(variable); + int result = 0x80000000; + + try { + result = Integer.parseInt(value); + } catch (NumberFormatException error) { + error.printStackTrace(); + logger.error(error.getMessage()); + } + + return result; + } + + public static String getStackTrace(Exception exception) { + StringWriter stringWriter = new StringWriter(); + exception.printStackTrace(new PrintWriter(stringWriter)); + return stringWriter.toString(); + } + + public static boolean isObjectIdValid(String input) { + ObjectId id = null; + try { + id = new ObjectId(input); // check if an ObjectId can be created from the string + if (id.toString().equalsIgnoreCase(input)) return true; + logger.warn("The input string does not have the same value as it's string representation."); + } catch (IllegalArgumentException e) { + logger.error(String.format("An ObjectId cannot be instantiated from the string: %s", input)); + } + + return false; + } + + public static boolean isPortValid(int port) { + return (port >= 0 && port <= 65535); + } + + public static boolean isHostValid(String host) { + return host.startsWith("http"); + } + + public static boolean identifierExistsInCollection( + MongoRepository repository, ObjectId identifier) { + return repository.findById(identifier.toString()).isPresent(); + } + + public static T findByIdGeneric(MongoRepository repository, ObjectId identifier) { + Optional optionalObj = repository.findById(identifier.toString()); + return optionalObj.orElse(null); + } + + public static String[] decodeBase64AuthorizationHeader(String encodedHeader) { + try { + byte[] decodedAuthorization = Base64.getDecoder().decode(encodedHeader.replace("Basic ", "")); + String credentials = new String(decodedAuthorization); + return credentials.split(":"); + } catch (Exception e) { + logger.error("Unable to decode authorization header: " + encodedHeader); + return null; + } + } + + public static User findUserByMechanizedId(String mechanizedId, UserRepository userRepository) { + Optional optionalUser = userRepository.findFirstByEmail(mechanizedId); + return optionalUser.orElse(null); + } + + public static User findUserByAuthHeader(String authorization, UserRepository userRepository) { + try { + if (Strings.isNullOrEmpty(authorization)) { + return null; + } + String[] credentials = Utilities.decodeBase64AuthorizationHeader(authorization); + return findUserByMechanizedId(credentials[0], userRepository); + } catch (Exception e) { + return null; + } + } + + public static T resolveOptional(Optional optional) { + return optional.orElse(null); + } + + public static T mapRequest(Class targetType, String input) { + logger.info(targetType.getName()); + + ObjectMapper mapper = + new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + try { + return mapper.readValue(input, targetType); + } catch (IOException e) { + Utilities.printStackTrace(e, LogLevel.ERROR); + return null; + } + } + + public enum LogLevel { + WARN, + DEBUG, + INFO, + ERROR + } + + public static Date getCurrentDate() { + return new Date(System.currentTimeMillis()); + } + + public static Map replaceObjectId(Map map, String objectIdKey) { + if (map.containsKey(objectIdKey)) { + ObjectId id = (ObjectId) map.get(objectIdKey); + map.replace(objectIdKey, id.toString()); + } + + return map; + } +}