diff options
Diffstat (limited to 'aai-traversal/src/main/java/org')
34 files changed, 1111 insertions, 1126 deletions
diff --git a/aai-traversal/src/main/java/org/onap/aai/Profiles.java b/aai-traversal/src/main/java/org/onap/aai/Profiles.java new file mode 100644 index 0000000..0b1292d --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/Profiles.java @@ -0,0 +1,12 @@ +package org.onap.aai; + +public final class Profiles { + + public static final String DMAAP = "dmaap"; + public static final String DME2 = "dme2"; + + public static final String ONE_WAY_SSL = "one-way-ssl"; + public static final String TWO_WAY_SSL = "two-way-ssl"; + + private Profiles(){} +} diff --git a/aai-traversal/src/main/java/org/onap/aai/TraversalApp.java b/aai-traversal/src/main/java/org/onap/aai/TraversalApp.java new file mode 100644 index 0000000..fb97908 --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/TraversalApp.java @@ -0,0 +1,130 @@ +package org.onap.aai; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.onap.aai.config.PropertyPasswordConfiguration; +import org.onap.aai.dbmap.AAIGraph; +import org.onap.aai.exceptions.AAIException; +import org.onap.aai.introspection.ModelInjestor; +import org.onap.aai.logging.LoggingContext; +import org.onap.aai.util.AAIConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.core.env.Environment; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import java.util.UUID; + +@SpringBootApplication +// Component Scan provides a way to look for spring beans +// It only searches beans in the following packages +// Any method annotated with @Bean annotation or any class +// with @Component, @Configuration, @Service will be picked up +@ComponentScan(basePackages = { + "org.onap.aai.config", + "org.onap.aai.web", + "org.onap.aai.tasks", + "org.onap.aai.rest", + "com.att.ajsc.common" +}) +@EnableAutoConfiguration(exclude = { + DataSourceAutoConfiguration.class, + DataSourceTransactionManagerAutoConfiguration.class, + HibernateJpaAutoConfiguration.class +}) +public class TraversalApp { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(TraversalApp.class.getName()); + + private static final String APP_NAME = "aai-traversal"; + + @Autowired + private Environment env; + + @PostConstruct + private void init() throws AAIException { + System.setProperty("org.onap.aai.serverStarted", "false"); + setDefaultProps(); + + LoggingContext.save(); + LoggingContext.component("init"); + LoggingContext.partnerName("NA"); + LoggingContext.targetEntity(APP_NAME); + LoggingContext.requestId(UUID.randomUUID().toString()); + LoggingContext.serviceName(APP_NAME); + LoggingContext.targetServiceName("contextInitialized"); + + logger.info("AAI Server initialization started..."); + + // Setting this property to allow for encoded slash (/) in the path parameter + // This is only needed for tomcat keeping this as temporary + System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true"); + + logger.info("Starting AAIGraph connections and the ModelInjestor"); + + if(env.acceptsProfiles(Profiles.TWO_WAY_SSL) && env.acceptsProfiles(Profiles.ONE_WAY_SSL)){ + logger.warn("You have seriously misconfigured your application"); + } + + AAIConfig.init(); + ModelInjestor.getInstance(); + AAIGraph.getInstance(); + } + + @PreDestroy + public void cleanup(){ + logger.info("Shutting down both realtime and cached connections"); + AAIGraph.getInstance().graphShutdown(); + } + + public static void main(String[] args) { + + setDefaultProps(); + SpringApplication app = new SpringApplication(TraversalApp.class); + app.setRegisterShutdownHook(true); + app.addInitializers(new PropertyPasswordConfiguration()); + Environment env = app.run(args).getEnvironment(); + + logger.info( + "Application '{}' is running on {}!" , + env.getProperty("spring.application.name"), + env.getProperty("server.port") + ); + + logger.info("Traversal MicroService Started"); + logger.error("Traversal MicroService Started"); + logger.debug("Traversal MicroService Started"); + System.out.println("Traversal Microservice Started"); + } + + public static void setDefaultProps(){ + + if (System.getProperty("file.separator") == null) { + System.setProperty("file.separator", "/"); + } + + String currentDirectory = System.getProperty("user.dir"); + + if (System.getProperty("AJSC_HOME") == null) { + System.setProperty("AJSC_HOME", "."); + } + + if(currentDirectory.contains(APP_NAME)){ + if (System.getProperty("BUNDLECONFIG_DIR") == null) { + System.setProperty("BUNDLECONFIG_DIR", "src/main/resources"); + } + } else { + if (System.getProperty("BUNDLECONFIG_DIR") == null) { + System.setProperty("BUNDLECONFIG_DIR", "aai-traversal/src/main/resources"); + } + } + + } +} diff --git a/aai-traversal/src/main/java/org/onap/aai/ajsc_aai/JaxrsErrorMessageLookupService.java b/aai-traversal/src/main/java/org/onap/aai/ajsc_aai/JaxrsErrorMessageLookupService.java deleted file mode 100644 index 6aa1f29..0000000 --- a/aai-traversal/src/main/java/org/onap/aai/ajsc_aai/JaxrsErrorMessageLookupService.java +++ /dev/null @@ -1,99 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.ajsc_aai; - -//import java.util.HashMap; -//import java.util.Map; - -//import javax.ws.rs.GET; -//import javax.ws.rs.HeaderParam; -//import javax.ws.rs.Path; -//import javax.ws.rs.PathParam; -//import javax.ws.rs.Produces; - -//import org.slf4j.Logger; -//import org.slf4j.LoggerFactory; -//import org.springframework.web.context.ContextLoader; -//import org.springframework.web.context.WebApplicationContext; - -//import ajsc.ErrorMessageLookupService; - -//@Path("/errormessage") -//public class JaxrsErrorMessageLookupService { - - //private final static Logger logger = LoggerFactory - //.getLogger(ErrorMessageLookupService.class); - - //* - //Gets the message. - - //@param input the input - //@param errorCode the error code - //@param appId the app id - //@param operation the operation - //@param messageText the message text - //@param isRESTService the is REST service - //@param faultEntity the fault entity - //@param ConvID the conv ID - //@return the message - //@GET - //@Path("/emls") - //@Produces("text/plain") - //public String getMessage(@PathParam("input") String input, - //@HeaderParam("errorCode") String errorCode, - //@HeaderParam("appId") String appId, - //@HeaderParam("operation") String operation, - //@HeaderParam("messageText") String messageText, - //@HeaderParam("isRESTService") String isRESTService, - //@HeaderParam("faultEntity") String faultEntity, - //@HeaderParam("ConvID") String ConvID) { - - //Map<String, String> headers = new HashMap<String, String>(); - //headers.put(errorCode, errorCode); - //headers.put(appId, appId); - //headers.put(operation, operation); - //headers.put(messageText, messageText); - //headers.put(isRESTService, isRESTService); - //headers.put(faultEntity, faultEntity); - //headers.put(ConvID, ConvID); - - //WebApplicationContext applicationContext = ContextLoader - //.getCurrentWebApplicationContext(); - - //ErrorMessageLookupService e = (ErrorMessageLookupService) applicationContext - //.getBean("errorMessageLookupService"); - - //String message = e.getExceptionDetails(appId, operation, errorCode, - //messageText,isRESTService, faultEntity, ConvID); - - //System.out.println("Error code = " + errorCode); - //System.out.println("appId = " + appId); - //System.out.println("operation = " + operation); - //System.out.println("messageText = " + messageText); - //System.out.println("isRESTService = " + isRESTService); - //System.out.println("faultEntity = " + faultEntity); - //System.out.println("ConvID = " + ConvID); - //return "The exception message is:\n " + message; - //} - -//} - diff --git a/aai-traversal/src/main/java/org/onap/aai/ajsc_aai/JaxrsUserService.java b/aai-traversal/src/main/java/org/onap/aai/ajsc_aai/JaxrsUserService.java deleted file mode 100644 index 29cf62a..0000000 --- a/aai-traversal/src/main/java/org/onap/aai/ajsc_aai/JaxrsUserService.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.ajsc_aai; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import java.util.Map; -import java.util.HashMap; - -@Path("/user") -public class JaxrsUserService { - - private static final Map<String,String> userIdToNameMap; - static { - userIdToNameMap = new HashMap<>(); - userIdToNameMap.put("userID1","Name1"); - userIdToNameMap.put("userID2","Name2"); - } - - /** - * Lookup user. - * - * @param userId the user id - * @return the string - */ - @GET - @Path("/{userId}") - @Produces("text/plain") - public String lookupUser(@PathParam("userId") String userId) { - String name = userIdToNameMap.get(userId); - return name != null ? name : "unknown id"; - } - -} diff --git a/aai-traversal/src/main/java/org/onap/aai/ajsc_aai/filemonitor/ServicePropertiesListener.java b/aai-traversal/src/main/java/org/onap/aai/ajsc_aai/filemonitor/ServicePropertiesListener.java deleted file mode 100644 index c806045..0000000 --- a/aai-traversal/src/main/java/org/onap/aai/ajsc_aai/filemonitor/ServicePropertiesListener.java +++ /dev/null @@ -1,21 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. - */ diff --git a/aai-traversal/src/main/java/org/onap/aai/ajsc_aai/filemonitor/ServicePropertiesMap.java b/aai-traversal/src/main/java/org/onap/aai/ajsc_aai/filemonitor/ServicePropertiesMap.java deleted file mode 100644 index 7274c61..0000000 --- a/aai-traversal/src/main/java/org/onap/aai/ajsc_aai/filemonitor/ServicePropertiesMap.java +++ /dev/null @@ -1,127 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.ajsc_aai.filemonitor; - -import java.io.File; -import java.io.FileInputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; - -public class ServicePropertiesMap -{ - private static HashMap<String, HashMap<String, String>> mapOfMaps = new HashMap<String, HashMap<String, String>>(); - private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(ServicePropertiesMap.class); - - /** - * Refresh. - * - * @param file the file - * @throws Exception the exception - */ - public static void refresh(File file) throws Exception - { - try - { - LOGGER.info("Loading properties - " + (file != null?file.getName():"")); - - //Store .json & .properties files into map of maps - String filePath = file.getPath(); - - if(filePath.lastIndexOf(".json")>0){ - - ObjectMapper om = new ObjectMapper(); - TypeReference<HashMap<String, String>> typeRef = new TypeReference<HashMap<String, String>>() {}; - HashMap<String, String> propMap = om.readValue(file, typeRef); - HashMap<String, String> lcasePropMap = new HashMap<String, String>(); - for (String key : propMap.keySet() ) - { - String lcaseKey = ifNullThenEmpty(key); - lcasePropMap.put(lcaseKey, propMap.get(key)); - } - - mapOfMaps.put(file.getName(), lcasePropMap); - - - }else if(filePath.lastIndexOf(".properties")>0){ - Properties prop = new Properties(); - FileInputStream fis = new FileInputStream(file); - prop.load(fis); - - @SuppressWarnings("unchecked") - HashMap<String, String> propMap = new HashMap<String, String>((Map)prop); - - mapOfMaps.put(file.getName(), propMap); - } - - LOGGER.info("File - " + file.getName() + " is loaded into the map and the corresponding system properties have been refreshed"); - } - catch (Exception e) - { - LOGGER.error("File " + (file != null?file.getName():"") + " cannot be loaded into the map ", e); - throw new Exception("Error reading map file " + (file != null?file.getName():""), e); - } - } - - /** - * Gets the property. - * - * @param fileName the file name - * @param propertyKey the property key - * @return the property - */ - public static String getProperty(String fileName, String propertyKey) - { - HashMap<String, String> propMap = mapOfMaps.get(fileName); - return propMap!=null?propMap.get(ifNullThenEmpty(propertyKey)):""; - } - - /** - * Gets the properties. - * - * @param fileName the file name - * @return the properties - */ - public static HashMap<String, String> getProperties(String fileName){ - return mapOfMaps.get(fileName); - } - - /** - * If null then empty. - * - * @param key the key - * @return the string - */ - private static String ifNullThenEmpty(String key) { - if (key == null) { - return ""; - } else { - return key; - } - } - -} diff --git a/aai-traversal/src/main/java/org/onap/aai/ajsc_aai/filemonitor/ServicePropertyService.java b/aai-traversal/src/main/java/org/onap/aai/ajsc_aai/filemonitor/ServicePropertyService.java deleted file mode 100644 index c806045..0000000 --- a/aai-traversal/src/main/java/org/onap/aai/ajsc_aai/filemonitor/ServicePropertyService.java +++ /dev/null @@ -1,21 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. - */ diff --git a/aai-traversal/src/main/java/org/onap/aai/ajsc_aai/util/ServicePropertiesMapBean.java b/aai-traversal/src/main/java/org/onap/aai/ajsc_aai/util/ServicePropertiesMapBean.java deleted file mode 100644 index 71c290b..0000000 --- a/aai-traversal/src/main/java/org/onap/aai/ajsc_aai/util/ServicePropertiesMapBean.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.ajsc_aai.util; - -import org.onap.aai.ajsc_aai.filemonitor.ServicePropertiesMap; - -public class ServicePropertiesMapBean { - - /** - * Gets the property. - * - * @param propFileName the prop file name - * @param propertyKey the property key - * @return the property - */ - public static String getProperty(String propFileName, String propertyKey) { - return ServicePropertiesMap.getProperty(propFileName, propertyKey); - } -} diff --git a/aai-traversal/src/main/java/org/onap/aai/config/DmaapConfig.java b/aai-traversal/src/main/java/org/onap/aai/config/DmaapConfig.java deleted file mode 100644 index 247ecf7..0000000 --- a/aai-traversal/src/main/java/org/onap/aai/config/DmaapConfig.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.config; - -import org.apache.activemq.broker.BrokerService; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -public class DmaapConfig { - - @Bean(destroyMethod = "stop") - public BrokerService brokerService() throws Exception { - - BrokerService broker = new BrokerService(); - broker.addConnector("tcp://localhost:61446"); - broker.setPersistent(false); - broker.setUseJmx(false); - broker.setSchedulerSupport(false); - broker.start(); - - return broker; - } -} diff --git a/aai-traversal/src/main/java/org/onap/aai/config/JettyPasswordDecoder.java b/aai-traversal/src/main/java/org/onap/aai/config/JettyPasswordDecoder.java new file mode 100644 index 0000000..069d71b --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/config/JettyPasswordDecoder.java @@ -0,0 +1,14 @@ +package org.onap.aai.config; + +import org.eclipse.jetty.util.security.Password; + +public class JettyPasswordDecoder implements PasswordDecoder { + + @Override + public String decode(String input) { + if (input.startsWith("OBF:")) { + return Password.deobfuscate(input); + } + return Password.deobfuscate("OBF:" + input); + } +} diff --git a/aai-traversal/src/main/java/org/onap/aai/config/PasswordDecoder.java b/aai-traversal/src/main/java/org/onap/aai/config/PasswordDecoder.java new file mode 100644 index 0000000..131bc6e --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/config/PasswordDecoder.java @@ -0,0 +1,6 @@ +package org.onap.aai.config; + +public interface PasswordDecoder { + + String decode(String input); +} diff --git a/aai-traversal/src/main/java/org/onap/aai/config/PropertyPasswordConfiguration.java b/aai-traversal/src/main/java/org/onap/aai/config/PropertyPasswordConfiguration.java new file mode 100644 index 0000000..a282f85 --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/config/PropertyPasswordConfiguration.java @@ -0,0 +1,62 @@ +package org.onap.aai.config; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.CompositePropertySource; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.EnumerablePropertySource; +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.env.PropertySource; +import org.springframework.stereotype.Component; + +public class PropertyPasswordConfiguration implements ApplicationContextInitializer<ConfigurableApplicationContext> { + + private static final Pattern decodePasswordPattern = Pattern.compile("password\\((.*?)\\)"); + + private PasswordDecoder passwordDecoder = new JettyPasswordDecoder(); + + @Override + public void initialize(ConfigurableApplicationContext applicationContext) { + ConfigurableEnvironment environment = applicationContext.getEnvironment(); + for (PropertySource<?> propertySource : environment.getPropertySources()) { + Map<String, Object> propertyOverrides = new LinkedHashMap<>(); + decodePasswords(propertySource, propertyOverrides); + if (!propertyOverrides.isEmpty()) { + PropertySource<?> decodedProperties = new MapPropertySource("decoded "+ propertySource.getName(), propertyOverrides); + environment.getPropertySources().addBefore(propertySource.getName(), decodedProperties); + } + } + } + + private void decodePasswords(PropertySource<?> source, Map<String, Object> propertyOverrides) { + if (source instanceof EnumerablePropertySource) { + EnumerablePropertySource<?> enumerablePropertySource = (EnumerablePropertySource<?>) source; + for (String key : enumerablePropertySource.getPropertyNames()) { + Object rawValue = source.getProperty(key); + if (rawValue instanceof String) { + String decodedValue = decodePasswordsInString((String) rawValue); + propertyOverrides.put(key, decodedValue); + } + } + } + } + + private String decodePasswordsInString(String input) { + if (input == null) return null; + StringBuffer output = new StringBuffer(); + Matcher matcher = decodePasswordPattern.matcher(input); + while (matcher.find()) { + String replacement = passwordDecoder.decode(matcher.group(1)); + matcher.appendReplacement(output, replacement); + } + matcher.appendTail(output); + return output.toString(); + } + +} diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/AAIContainerFilter.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/AAIContainerFilter.java new file mode 100644 index 0000000..062cb27 --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/interceptors/AAIContainerFilter.java @@ -0,0 +1,22 @@ +package org.onap.aai.interceptors; + +import java.util.UUID; + +import org.onap.aai.util.FormatDate; + +public abstract class AAIContainerFilter { + + protected String genDate() { + FormatDate fd = new FormatDate("YYMMdd-HH:mm:ss:SSS"); + return fd.getDateTime(); + } + + protected boolean isValidUUID(String transId) { + try { + UUID.fromString(transId); + } catch (IllegalArgumentException e) { + return false; + } + return true; + } +} diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/AAIHeaderProperties.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/AAIHeaderProperties.java index 733383a..8eca9b6 100644 --- a/aai-traversal/src/main/java/org/onap/aai/interceptors/AAIHeaderProperties.java +++ b/aai-traversal/src/main/java/org/onap/aai/interceptors/AAIHeaderProperties.java @@ -21,7 +21,21 @@ */ package org.onap.aai.interceptors; -public class AAIHeaderProperties { - +public final class AAIHeaderProperties { + + private AAIHeaderProperties(){} + public static final String REQUEST_CONTEXT = "aai-request-context"; + + public static final String HTTP_METHOD_OVERRIDE = "X-HTTP-Method-Override"; + + public static final String TRANSACTION_ID = "X-TransactionId"; + + public static final String FROM_APP_ID = "X-FromAppId"; + + public static final String AAI_TX_ID = "X-AAI-TXID"; + + public static final String AAI_REQUEST = "X-REQUEST"; + + public static final String AAI_REQUEST_TS = "X-REQUEST-TS"; } diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/AAILogJAXRSInInterceptor.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/AAILogJAXRSInInterceptor.java deleted file mode 100644 index 155d387..0000000 --- a/aai-traversal/src/main/java/org/onap/aai/interceptors/AAILogJAXRSInInterceptor.java +++ /dev/null @@ -1,286 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.interceptors; - -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.ws.rs.core.MediaType; - -import org.apache.commons.io.IOUtils; -import org.apache.cxf.helpers.CastUtils; -import org.apache.cxf.interceptor.LoggingMessage; -import org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor; -import org.apache.cxf.message.Message; -import org.onap.aai.exceptions.AAIException; -import org.onap.aai.logging.ErrorLogHelper; -import org.onap.aai.rest.util.EchoResponse; -import org.onap.aai.util.AAIConfig; -import org.onap.aai.util.AAIConstants; -import org.onap.aai.util.FormatDate; -import org.onap.aai.util.HbaseSaltPrefixer; - -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; -import org.slf4j.MDC; - -public class AAILogJAXRSInInterceptor extends JAXRSInInterceptor { - - protected final String COMPONENT = "aairest"; - protected final String CAMEL_REQUEST ="CamelHttpUrl"; - private static final Pattern uuidPattern = Pattern.compile("^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"); - private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(AAILogJAXRSInInterceptor.class); - - /** - * {@inheritDoc} - */ - public void handleMessage(Message message) { - - boolean go = false; - String uri = null; - String query = null; - try { - - uri = (String)message.get(CAMEL_REQUEST); - if (uri != null) { - query = (String)message.get(Message.QUERY_STRING); - } - - if (AAIConfig.get(AAIConstants.AAI_LOGGING_HBASE_INTERCEPTOR).equalsIgnoreCase("true") && - AAIConfig.get(AAIConstants.AAI_LOGGING_HBASE_ENABLED).equalsIgnoreCase("true")) { - go = true; - message.getExchange().put("AAI_LOGGING_HBASE_ENABLED", 1); - if (AAIConfig.get(AAIConstants.AAI_LOGGING_HBASE_LOGREQUEST).equalsIgnoreCase("true") ) { - message.getExchange().put("AAI_LOGGING_HBASE_LOGREQUEST", 1); - } - if (AAIConfig.get(AAIConstants.AAI_LOGGING_HBASE_LOGRESPONSE).equalsIgnoreCase("true") ) { - message.getExchange().put("AAI_LOGGING_HBASE_LOGRESPONSE", 1); - } - } - if (AAIConfig.get(AAIConstants.AAI_LOGGING_TRACE_ENABLED).equalsIgnoreCase("true") ) { - go = true; - message.getExchange().put("AAI_LOGGING_TRACE_ENABLED", 1); - if (AAIConfig.get(AAIConstants.AAI_LOGGING_TRACE_LOGREQUEST).equalsIgnoreCase("true") ) { - message.getExchange().put("AAI_LOGGING_TRACE_LOGREQUEST", 1); - } - if (AAIConfig.get(AAIConstants.AAI_LOGGING_TRACE_LOGRESPONSE).equalsIgnoreCase("true") ) { - message.getExchange().put("AAI_LOGGING_TRACE_LOGRESPONSE", 1); - } - } - } catch (AAIException e1) { - ErrorLogHelper.logException(e1); - } - - if ((uri != null) && (uri.contains(EchoResponse.echoPath))) { - // if it's a health check, we don't want to log ANYTHING if it's a lightweight one - if (query == null) { - if (message.getExchange().containsKey("AAI_LOGGING_HBASE_ENABLED")) { - message.getExchange().remove("AAI_LOGGING_HBASE_ENABLED"); - } - if (message.getExchange().containsKey("AAI_LOGGING_TRACE_ENABLED")) { - message.getExchange().remove("AAI_LOGGING_TRACE_ENABLED"); - } - go = false; - } - } - else if ((uri != null) && (uri.contains("/translog/"))) { - // if it's a translog query, we don't want to log the responses - if (message.getExchange().containsKey("AAI_LOGGING_HBASE_LOGRESPONSE")) { - message.getExchange().remove("AAI_LOGGING_HBASE_LOGRESPONSE"); - } - if (message.getExchange().containsKey("AAI_LOGGING_TRACE_LOGRESPONSE")) { - message.getExchange().remove("AAI_LOGGING_TRACE_LOGRESPONSE"); - } - } - - if (go == false) { // there's nothing to do - return; - } - - // DONE: get a TXID based on hostname, time (YYYYMMDDHHMMSSMILLIS, and LoggingMessage.nextId(); 20150326145301-1 - String now = genDate(); - - message.getExchange().put("AAI_RQST_TM", now); - - String id = (String)message.getExchange().get(LoggingMessage.ID_KEY); - - String fullId = null; - try { - if (id == null) { - id = LoggingMessage.nextId(); - } - fullId = AAIConfig.get(AAIConstants.AAI_NODENAME) + "-" + now + "-" + id; - fullId = HbaseSaltPrefixer.getInstance().prependSalt(fullId); - message.getExchange().put(LoggingMessage.ID_KEY, fullId); - } catch (AAIException e1) { - LOGGER.debug("config problem", e1); - } - - if (fullId == null) { - fullId = now + "-" + id; - fullId = HbaseSaltPrefixer.getInstance().prependSalt(fullId); - } - message.put(LoggingMessage.ID_KEY, fullId); - final LoggingMessage buffer = new LoggingMessage("Message", fullId); - - Integer responseCode = (Integer)message.get(Message.RESPONSE_CODE); - if (responseCode != null) { - buffer.getResponseCode().append(responseCode); - } - - String encoding = (String)message.get(Message.ENCODING); - - if (encoding != null) { - buffer.getEncoding().append(encoding); - } - String httpMethod = (String)message.get(Message.HTTP_REQUEST_METHOD); - if (httpMethod != null) { - buffer.getHttpMethod().append(httpMethod); - } - - String ct = (String)message.get(Message.CONTENT_TYPE); - if (ct != null) { - if ("*/*".equals(ct)) { - message.put(Message.CONTENT_TYPE, MediaType.APPLICATION_JSON); - ct = MediaType.APPLICATION_JSON; - } - buffer.getContentType().append(ct); - - } - Object headers = message.get(Message.PROTOCOL_HEADERS); - if (headers != null) { - buffer.getHeader().append(headers); - - Map<String, List<String>> headersList = CastUtils.cast((Map<?, ?>)message.get(Message.PROTOCOL_HEADERS)); - String transId = ""; - List<String> xt = headersList.get("X-TransactionId"); - String newTransId = transId; - boolean missingTransId = false; - boolean replacedTransId = false; - String logMsg = null; - if (xt != null) { - for (String transIdValue : xt) { - transId = transIdValue; - } - Matcher matcher = uuidPattern.matcher(transId); - if (!matcher.find()) { - replacedTransId = true; - // check if there's a colon, and check the first group? - if (transId.contains(":")) { - String[] uuidParts = transId.split(":"); - Matcher matcher2 = uuidPattern.matcher(uuidParts[0]); - if (matcher2.find()) { - newTransId = uuidParts[0]; - } else { - // punt, we tried to find it, it has a colon but no UUID-1 - newTransId = UUID.randomUUID().toString(); - } - } else { - newTransId = UUID.randomUUID().toString(); - } - } - } else { - newTransId = UUID.randomUUID().toString(); - missingTransId = true; - } - - if (missingTransId || replacedTransId) { - List<String> txList = new ArrayList<String>(); - txList.add(newTransId); - headersList.put("X-TransactionId", txList); - if (missingTransId) { - logMsg = "Missing requestID. Assigned " + newTransId; - } else if (replacedTransId) { - logMsg = "Replaced invalid requestID of " + transId + " Assigned " + newTransId; - } - MDC.put("RequestId",newTransId); - } - else { - MDC.put("RequestId",transId); - } - - - List<String> fromAppIdList = headersList.get("X-FromAppId"); - if (fromAppIdList != null) { - String fromAppId = null; - for (String fromAppIdValue : fromAppIdList) { - fromAppId = fromAppIdValue; - } - MDC.put("PartnerName",fromAppId); - } - - List<String> contentType = headersList.get("Content-Type"); - if (contentType == null) { - ct = (String)message.get(Message.CONTENT_TYPE); - headersList.put(Message.CONTENT_TYPE, Collections.singletonList(ct)); - } - - LOGGER.auditEvent("REST " + httpMethod + " " + ((query != null)? uri+"?"+query : uri) + " HbaseTxId=" + fullId); - LOGGER.info(logMsg); - } - - - if (uri != null) { - buffer.getAddress().append(uri); - if (query != null) { - buffer.getAddress().append("?").append(query); - } - } - - InputStream is = message.getContent(InputStream.class); - if (is != null) { - try { - String currentPayload = IOUtils.toString(is, "UTF-8"); - IOUtils.closeQuietly(is); - buffer.getPayload().append(currentPayload); - is = IOUtils.toInputStream(currentPayload, "UTF-8"); - message.setContent(InputStream.class, is); - IOUtils.closeQuietly(is); - } catch (Exception e) { - // It's ok to not have request input content - // throw new Fault(e); - } - } - - // this will be saved in the message exchange, and can be pulled out later... - message.getExchange().put(fullId + "_REQUEST", buffer.toString()); - } - - /** - * Gen date. - * - * @param aaiLogger the aai logger - * @param logline the logline - * @return the string - */ - protected String genDate() { - FormatDate fd = new FormatDate("YYMMdd-HH:mm:ss:SSS"); - return fd.getDateTime(); - } - -} diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/AAILogJAXRSOutInterceptor.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/AAILogJAXRSOutInterceptor.java deleted file mode 100644 index a280023..0000000 --- a/aai-traversal/src/main/java/org/onap/aai/interceptors/AAILogJAXRSOutInterceptor.java +++ /dev/null @@ -1,303 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.interceptors; - -import java.io.OutputStream; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.cxf.helpers.CastUtils; -import org.apache.cxf.interceptor.LoggingMessage; -import org.apache.cxf.io.CacheAndWriteOutputStream; -import org.apache.cxf.io.CachedOutputStream; -import org.apache.cxf.io.CachedOutputStreamCallback; -import org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor; -import org.apache.cxf.message.Message; -import org.onap.aai.exceptions.AAIException; -import org.onap.aai.logging.ErrorLogHelper; -import org.onap.aai.util.AAIConfig; -import org.onap.aai.util.AAIConstants; -import org.onap.aai.util.FormatDate; - -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; - -// right after the request is complete, there may be content -public class AAILogJAXRSOutInterceptor extends JAXRSOutInterceptor { - - private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(AAILogJAXRSOutInterceptor.class); - - protected final String COMPONENT = "aairest"; - protected final String CAMEL_REQUEST = "CamelHttpUrl"; - - /** - * {@inheritDoc} - */ - public void handleMessage(Message message) { - - String fullId = (String) message.getExchange().get(LoggingMessage.ID_KEY); - - Map<String, List<String>> headers = CastUtils.cast((Map<?, ?>) message.get(Message.PROTOCOL_HEADERS)); - if (headers == null) { - headers = new HashMap<String, List<String>>(); - } - - headers.put("X-AAI-TXID", Collections.singletonList(fullId)); - message.put(Message.PROTOCOL_HEADERS, headers); - - Message outMessage = message.getExchange().getOutMessage(); - final OutputStream os = outMessage.getContent(OutputStream.class); - if (os == null) { - return; - } - - // we only want to register the callback if there is good reason for it. - if (message.getExchange().containsKey("AAI_LOGGING_HBASE_ENABLED") || message.getExchange().containsKey("AAI_LOGGING_TRACE_ENABLED")) { - - final CacheAndWriteOutputStream newOut = new CacheAndWriteOutputStream(os); - message.setContent(OutputStream.class, newOut); - newOut.registerCallback(new LoggingCallback(message, os)); - } - - } - - class LoggingCallback implements CachedOutputStreamCallback { - - private final Message message; - private final OutputStream origStream; - - public LoggingCallback(final Message msg, final OutputStream os) { - this.message = msg; - this.origStream = os; - } - - public void onFlush(CachedOutputStream cos) { - - } - - public void onClose(CachedOutputStream cos) { - - String getValue = ""; - String postValue = ""; - String logValue = ""; - - try { - logValue = AAIConfig.get("aai.transaction.logging"); - getValue = AAIConfig.get("aai.transaction.logging.get"); - postValue = AAIConfig.get("aai.transaction.logging.post"); - } catch (AAIException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - if (!message.getExchange().containsKey("AAI_LOGGING_HBASE_ENABLED") && !message.getExchange().containsKey("AAI_LOGGING_TRACE_ENABLED")) { - return; - } - - String fullId = (String) message.getExchange().get(LoggingMessage.ID_KEY); - - Message inMessage = message.getExchange().getInMessage(); - String transId = null; - String fromAppId = null; - - Map<String, List<String>> headersList = CastUtils.cast((Map<?, ?>) inMessage.get(Message.PROTOCOL_HEADERS)); - if (headersList != null) { - List<String> xt = headersList.get("X-TransactionId"); - if (xt != null) { - for (String transIdValue : xt) { - transId = transIdValue; - } - } - List<String> fa = headersList.get("X-FromAppId"); - if (fa != null) { - for (String fromAppIdValue : fa) { - - fromAppId = fromAppIdValue; - } - } - } - - String httpMethod = (String) inMessage.get(Message.HTTP_REQUEST_METHOD); - - String uri = (String) inMessage.get(CAMEL_REQUEST); - String fullUri = uri; - if (uri != null) { - String query = (String) message.get(Message.QUERY_STRING); - if (query != null) { - fullUri = uri + "?" + query; - } - } - - String request = (String) message.getExchange().get(fullId + "_REQUEST"); - - Message outMessage = message.getExchange().getOutMessage(); - - final LoggingMessage buffer = new LoggingMessage("OUTMessage", fullId); - - // should we check this, and make sure it's not an error? - Integer responseCode = (Integer) outMessage.get(Message.RESPONSE_CODE); - if (responseCode == null) { - responseCode = 200; // this should never happen, but just in - // case we don't get one - } - buffer.getResponseCode().append(responseCode); - - String encoding = (String) outMessage.get(Message.ENCODING); - - if (encoding != null) { - buffer.getEncoding().append(encoding); - } - - String ct = (String) outMessage.get(Message.CONTENT_TYPE); - if (ct != null) { - buffer.getContentType().append(ct); - } - - Object headers = outMessage.get(Message.PROTOCOL_HEADERS); - if (headers != null) { - buffer.getHeader().append(headers); - } - - Boolean ss = false; - if (responseCode >= 200 && responseCode <= 299) { - ss = true; - } - String response = buffer.toString(); - - // this should have been set by the in interceptor - String rqstTm = (String) message.getExchange().get("AAI_RQST_TM"); - - // just in case it wasn't, we'll put this here. not great, but it'll - // have a val. - if (rqstTm == null) { - rqstTm = genDate(); - } - - - String respTm = genDate(); - - try { - String actualRequest = request; - StringBuilder builder = new StringBuilder(); - cos.writeCacheTo(builder, 100000); - // here comes my xml: - String payload = builder.toString(); - - String actualResponse = response; - if (payload == null) { - - } else { - actualResponse = response + payload; - } - - // we only log to AAI log if it's eanbled in the config props - // file - if (message.getExchange().containsKey("AAI_LOGGING_TRACE_ENABLED")) { - - if (message.getExchange().containsKey("AAI_LOGGING_TRACE_LOGREQUEST")) { - - // strip newlines from request - String traceRequest = actualRequest; - traceRequest = traceRequest.replace("\n", " "); - traceRequest = traceRequest.replace("\r", ""); - traceRequest = traceRequest.replace("\t", ""); - LOGGER.debug(traceRequest); - } - if (message.getExchange().containsKey("AAI_LOGGING_TRACE_LOGRESPONSE")) { - // strip newlines from response - String traceResponse = actualResponse; - traceResponse = traceResponse.replace("\n", " "); - traceResponse = traceResponse.replace("\r", ""); - traceResponse = traceResponse.replace("\t", ""); - - LOGGER.debug(traceResponse); - } - } - - // we only log to HBASE if it's enabled in the config props file - // TODO: pretty print XML/JSON. we might need to get the payload - // and envelope seperately - if (message.getExchange().containsKey("AAI_LOGGING_HBASE_ENABLED")) { - if (!message.getExchange().containsKey("AAI_LOGGING_HBASE_LOGREQUEST")) { - actualRequest = "loggingDisabled"; - } - if (!message.getExchange().containsKey("AAI_LOGGING_HBASE_LOGRESPONSE")) { - actualResponse = "loggingDisabled"; - } - - LOGGER.debug("action={}, urlin={}, HbTransId={}", httpMethod, fullUri, fullId); - - if (logValue.equals("false")) { - } else if (getValue.equals("false") && httpMethod.equals("GET")) { - } else if (postValue.equals("false") && httpMethod.equals("POST")) { - } else { - putTransaction(transId, responseCode.toString(), rqstTm, respTm, fromAppId + ":" + transId, fullUri, httpMethod, request, response, actualResponse); - - } - } - } catch (Exception ex) { - // ignore - } - - message.setContent(OutputStream.class, origStream); - - LOGGER.auditEvent("HTTP Response Code: {}", responseCode.toString()); - } - - } - - protected String genDate() { - FormatDate fd = new FormatDate("YYMMdd-HH:mm:ss:SSS"); - return fd.getDateTime(); - } - - public String putTransaction(String tid, String status, String rqstTm, String respTm, String srcId, String rsrcId, String rsrcType, String rqstBuf, String respBuf, String actualResponse) { - String tm = null; - - if (tid == null || "".equals(tid)) { - tm = this.genDate(); - tid = tm + "-"; - } - - String htid = tid; - - if (rqstTm == null || "".equals(rqstTm)) { - rqstTm = tm; - } - - if (respTm == null || "".equals(respTm)) { - respTm = tm; - } - - try { - LOGGER.debug(" transactionId:" + tid + " status: " + status + " rqstDate: " + rqstTm + " respDate: " + respTm + " sourceId: " + srcId + " resourceId: " - + rsrcId + " resourceType: " + rsrcType + " payload rqstBuf: " + rqstBuf + " payload respBuf: " + respBuf + " Payload Error Messages: " + actualResponse); - return htid; - } catch (Exception e) { - ErrorLogHelper.logError("AAI_4000", "Exception updating HBase:"); - return htid; - } - - } -} diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/PostAaiAjscInterceptor.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/PostAaiAjscInterceptor.java deleted file mode 100644 index 1849b10..0000000 --- a/aai-traversal/src/main/java/org/onap/aai/interceptors/PostAaiAjscInterceptor.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.interceptors; - -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.onap.aai.logging.LoggingContext; -import org.onap.aai.logging.LoggingContext.StatusCode; -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; - -import ajsc.beans.interceptors.AjscInterceptor; - -public class PostAaiAjscInterceptor implements AjscInterceptor { - - private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(PostAaiAjscInterceptor.class); - - private static class LazyAaiAjscInterceptor { - public static final PostAaiAjscInterceptor INSTANCE = new PostAaiAjscInterceptor(); - } - - public static PostAaiAjscInterceptor getInstance() { - return LazyAaiAjscInterceptor.INSTANCE; - } - - @Override - public boolean allowOrReject(HttpServletRequest req, HttpServletResponse resp, Map<?, ?> paramMap) - throws Exception { - final int httpStatusCode = resp.getStatus(); - LoggingContext.responseCode(Integer.toString(httpStatusCode)); - if ( httpStatusCode < 200 || httpStatusCode > 299 ) { - LoggingContext.statusCode(StatusCode.ERROR); - LoggingContext.responseDescription("Error"); - LOGGER.error(req.getRequestURL() + " call failed with responseCode=" + httpStatusCode); - } - else { - LoggingContext.responseDescription(LoggingContext.responseMap.get(LoggingContext.SUCCESS)); - LoggingContext.statusCode(StatusCode.COMPLETE); - LOGGER.info(req.getRequestURL() + " call succeeded"); - } - LoggingContext.clear(); - return true; - } -} diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/PreAaiAjscInterceptor.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/PreAaiAjscInterceptor.java deleted file mode 100644 index b510d4b..0000000 --- a/aai-traversal/src/main/java/org/onap/aai/interceptors/PreAaiAjscInterceptor.java +++ /dev/null @@ -1,63 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.interceptors; - -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.onap.aai.logging.LoggingContext; - -import ajsc.beans.interceptors.AjscInterceptor; - -public class PreAaiAjscInterceptor implements AjscInterceptor { - private final static String TARGET_ENTITY = "aai-traversal"; - - private static class LazyAaiAjscInterceptor { - public static final PreAaiAjscInterceptor INSTANCE = new PreAaiAjscInterceptor(); - } - - public static PreAaiAjscInterceptor getInstance() { - return LazyAaiAjscInterceptor.INSTANCE; - } - - @Override - public boolean allowOrReject(HttpServletRequest req, HttpServletResponse resp, Map<?, ?> paramMap) - throws Exception { - - LoggingContext.init(); - - String serviceName = req.getMethod() + " " + req.getRequestURI().toString(); - LoggingContext.partnerName(req.getHeader("X-FromAppId")); - String queryStr = req.getQueryString(); - if ( queryStr != null ) { - serviceName = serviceName + "?" + queryStr; - } - LoggingContext.serviceName(serviceName); - LoggingContext.targetEntity(TARGET_ENTITY); - LoggingContext.targetServiceName("allowOrReject"); - LoggingContext.requestId(req.getHeader("X-TransactionId")); - LoggingContext.successStatusFields(); - return true; - } -} diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/package-info.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/package-info.java new file mode 100644 index 0000000..131d46c --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/interceptors/package-info.java @@ -0,0 +1,17 @@ +/** + * <b>Interceptors</b> package is subdivided to pre and post interceptors + * If you want to add an additional interceptor you would need to add + * the priority level to AAIRequestFilterPriority or AAIResponsePriority + * to give a value which indicates the order in which the interceptor + * will be triggered and also you will add that value like here + * + * <pre> + * <code> + * @Priority(AAIRequestFilterPriority.YOUR_PRIORITY) + * public class YourInterceptor extends AAIContainerFilter implements ContainerRequestFilter { + * + * } + * </code> + * </pre> + */ +package org.onap.aai.interceptors;
\ No newline at end of file diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/post/AAIResponseFilterPriority.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/post/AAIResponseFilterPriority.java new file mode 100644 index 0000000..d14c24f --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/interceptors/post/AAIResponseFilterPriority.java @@ -0,0 +1,13 @@ +package org.onap.aai.interceptors.post; + +public final class AAIResponseFilterPriority { + + private AAIResponseFilterPriority() {} + + public static final int HEADER_MANIPULATION = 1000; + + public static final int RESPONSE_TRANS_LOGGING = 2000; + + public static final int RESET_LOGGING_CONTEXT = 3000; + +} diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/post/ResetLoggingContext.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/post/ResetLoggingContext.java new file mode 100644 index 0000000..d1b74d2 --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/interceptors/post/ResetLoggingContext.java @@ -0,0 +1,50 @@ +package org.onap.aai.interceptors.post; + +import java.io.IOException; + +import javax.annotation.Priority; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.container.ContainerResponseFilter; + +import org.onap.aai.interceptors.AAIContainerFilter; +import org.onap.aai.logging.LoggingContext; +import org.onap.aai.logging.LoggingContext.StatusCode; +import org.springframework.beans.factory.annotation.Autowired; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +@Priority(AAIResponseFilterPriority.RESET_LOGGING_CONTEXT) +public class ResetLoggingContext extends AAIContainerFilter implements ContainerResponseFilter { + + private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(ResetLoggingContext.class); + + @Autowired + private HttpServletRequest httpServletRequest; + + @Override + public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) + throws IOException { + + this.cleanLoggingContext(); + + } + + private void cleanLoggingContext() { + final String responseCode = LoggingContext.responseCode(); + String url = httpServletRequest.getRequestURL().toString(); + + if (responseCode != null && responseCode.startsWith("ERR.")) { + LoggingContext.statusCode(StatusCode.ERROR); + LOGGER.error(url + " call failed with responseCode=" + responseCode); + } else { + LoggingContext.statusCode(StatusCode.COMPLETE); + LOGGER.info(url + " call succeeded"); + } + + LoggingContext.clear(); + } + +} diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/post/ResponseHeaderManipulation.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/post/ResponseHeaderManipulation.java new file mode 100644 index 0000000..a26334f --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/interceptors/post/ResponseHeaderManipulation.java @@ -0,0 +1,30 @@ +package org.onap.aai.interceptors.post; + +import java.io.IOException; + +import javax.annotation.Priority; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.container.ContainerResponseFilter; + +import org.onap.aai.interceptors.AAIContainerFilter; +import org.onap.aai.interceptors.AAIHeaderProperties; + +@Priority(AAIResponseFilterPriority.HEADER_MANIPULATION) +public class ResponseHeaderManipulation extends AAIContainerFilter implements ContainerResponseFilter { + + + @Override + public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) + throws IOException { + + updateResponseHeaders(requestContext, responseContext); + + } + + private void updateResponseHeaders(ContainerRequestContext requestContext, + ContainerResponseContext responseContext) { + responseContext.getHeaders().add(AAIHeaderProperties.AAI_TX_ID, requestContext.getProperty(AAIHeaderProperties.AAI_TX_ID)); + } + +} diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/post/ResponseTransactionLogging.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/post/ResponseTransactionLogging.java new file mode 100644 index 0000000..7b18e45 --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/interceptors/post/ResponseTransactionLogging.java @@ -0,0 +1,106 @@ +package org.onap.aai.interceptors.post; + +import java.io.IOException; +import java.util.Objects; +import java.util.Optional; + +import javax.annotation.Priority; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.container.ContainerResponseFilter; + +import org.onap.aai.exceptions.AAIException; +import org.onap.aai.interceptors.AAIContainerFilter; +import org.onap.aai.interceptors.AAIHeaderProperties; +import org.onap.aai.logging.ErrorLogHelper; +import org.onap.aai.util.AAIConfig; +import org.springframework.beans.factory.annotation.Autowired; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.google.gson.JsonObject; + +@Priority(AAIResponseFilterPriority.RESPONSE_TRANS_LOGGING) +public class ResponseTransactionLogging extends AAIContainerFilter implements ContainerResponseFilter { + + private static final EELFLogger TRANSACTION_LOGGER = EELFManager.getInstance().getLogger(ResponseTransactionLogging.class); + + @Autowired + private HttpServletResponse httpServletResponse; + + @Override + public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) + throws IOException { + + this.transLogging(requestContext, responseContext); + + } + + private void transLogging(ContainerRequestContext requestContext, ContainerResponseContext responseContext) { + + String logValue; + String getValue; + String postValue; + + try { + logValue = AAIConfig.get("aai.transaction.logging"); + getValue = AAIConfig.get("aai.transaction.logging.get"); + postValue = AAIConfig.get("aai.transaction.logging.post"); + } catch (AAIException e) { + return; + } + + String transId = requestContext.getHeaderString(AAIHeaderProperties.TRANSACTION_ID); + String fromAppId = requestContext.getHeaderString(AAIHeaderProperties.FROM_APP_ID); + String fullUri = requestContext.getUriInfo().getRequestUri().toString(); + String requestTs = (String)requestContext.getProperty(AAIHeaderProperties.AAI_REQUEST_TS); + + String httpMethod = requestContext.getMethod(); + + String status = Integer.toString(responseContext.getStatus()); + + String request = (String)requestContext.getProperty(AAIHeaderProperties.AAI_REQUEST); + String response = this.getResponseString(responseContext); + + if (!Boolean.parseBoolean(logValue)) { + } else if (!Boolean.parseBoolean(getValue) && "GET".equals(httpMethod)) { + } else if (!Boolean.parseBoolean(postValue) && "POST".equals(httpMethod)) { + } else { + + JsonObject logEntry = new JsonObject(); + logEntry.addProperty("transactionId", transId); + logEntry.addProperty("status", status); + logEntry.addProperty("rqstDate", requestTs); + logEntry.addProperty("respDate", this.genDate()); + logEntry.addProperty("sourceId", fromAppId + ":" + transId); + logEntry.addProperty("resourceId", fullUri); + logEntry.addProperty("resourceType", httpMethod); + logEntry.addProperty("rqstBuf", Objects.toString(request, "")); + logEntry.addProperty("respBuf", Objects.toString(response, "")); + + try { + TRANSACTION_LOGGER.debug(logEntry.toString()); + } catch (Exception e) { + ErrorLogHelper.logError("AAI_4000", "Exception writing transaction log."); + } + } + + } + + private String getResponseString(ContainerResponseContext responseContext) { + JsonObject response = new JsonObject(); + response.addProperty("ID", responseContext.getHeaderString(AAIHeaderProperties.AAI_TX_ID)); + response.addProperty("Content-Type", this.httpServletResponse.getContentType()); + response.addProperty("Response-Code", responseContext.getStatus()); + response.addProperty("Headers", responseContext.getHeaders().toString()); + Optional<Object> entityOptional = Optional.ofNullable(responseContext.getEntity()); + if(entityOptional.isPresent()){ + response.addProperty("Entity", entityOptional.get().toString()); + } else { + response.addProperty("Entity", ""); + } + return response.toString(); + } + +} diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/AAIRequestFilterPriority.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/AAIRequestFilterPriority.java new file mode 100644 index 0000000..b3fc1b1 --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/AAIRequestFilterPriority.java @@ -0,0 +1,18 @@ +package org.onap.aai.interceptors.pre; + +public final class AAIRequestFilterPriority { + + private AAIRequestFilterPriority() {} + + public static final int REQUEST_TRANS_LOGGING = 1000; + + public static final int HEADER_VALIDATION = 2000; + + public static final int SET_LOGGING_CONTEXT = 3000; + + public static final int AUTHORIZATION = 4000; + + public static final int HEADER_MANIPULATION = 5000; + + public static final int REQUEST_MODIFICATION = 6000; +} diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/HeaderValidation.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/HeaderValidation.java new file mode 100644 index 0000000..88a492f --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/HeaderValidation.java @@ -0,0 +1,88 @@ +/*- + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.aai.interceptors.pre; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import javax.annotation.Priority; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.container.PreMatching; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.onap.aai.exceptions.AAIException; +import org.onap.aai.interceptors.AAIContainerFilter; +import org.onap.aai.interceptors.AAIHeaderProperties; +import org.onap.aai.logging.ErrorLogHelper; + +@PreMatching +@Priority(AAIRequestFilterPriority.HEADER_VALIDATION) +public class HeaderValidation extends AAIContainerFilter implements ContainerRequestFilter { + + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + + Optional<Response> oResp; + + String transId = requestContext.getHeaderString(AAIHeaderProperties.TRANSACTION_ID); + String fromAppId = requestContext.getHeaderString(AAIHeaderProperties.FROM_APP_ID); + + List<MediaType> acceptHeaderValues = requestContext.getAcceptableMediaTypes(); + + oResp = this.validateHeaderValuePresence(fromAppId, "AAI_4009", acceptHeaderValues); + if (oResp.isPresent()) { + requestContext.abortWith(oResp.get()); + return; + } + oResp = this.validateHeaderValuePresence(transId, "AAI_4010", acceptHeaderValues); + if (oResp.isPresent()) { + requestContext.abortWith(oResp.get()); + return; + } + + if (!this.isValidUUID(transId)) { + transId = UUID.randomUUID().toString(); + requestContext.getHeaders().get(AAIHeaderProperties.TRANSACTION_ID).clear(); + requestContext.getHeaders().add(AAIHeaderProperties.TRANSACTION_ID, transId); + } + + } + + private Optional<Response> validateHeaderValuePresence(String value, String errorCode, + List<MediaType> acceptHeaderValues) { + Response response = null; + AAIException aaie; + if (value == null) { + aaie = new AAIException(errorCode); + return Optional.of(Response.status(aaie.getErrorObject().getHTTPResponseCode()) + .entity(ErrorLogHelper.getRESTAPIErrorResponse(acceptHeaderValues, aaie, new ArrayList<>())) + .build()); + } + + return Optional.ofNullable(response); + } + +} diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/RequestHeaderManipulation.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/RequestHeaderManipulation.java new file mode 100644 index 0000000..63a92cf --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/RequestHeaderManipulation.java @@ -0,0 +1,71 @@ +/*- + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.aai.interceptors.pre; + +import java.io.IOException; +import java.util.Collections; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.annotation.Priority; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.container.PreMatching; +import javax.ws.rs.core.MultivaluedMap; + +import org.onap.aai.interceptors.AAIContainerFilter; +import org.onap.aai.interceptors.AAIHeaderProperties; +import org.springframework.beans.factory.annotation.Autowired; + +@PreMatching +@Priority(AAIRequestFilterPriority.HEADER_MANIPULATION) +public class RequestHeaderManipulation extends AAIContainerFilter implements ContainerRequestFilter { + + @Autowired + private HttpServletRequest httpServletRequest; + + private static final Pattern versionedEndpoint = Pattern.compile("^/aai/(v\\d+)"); + + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + + String uri = httpServletRequest.getRequestURI(); + this.addRequestContext(uri, requestContext.getHeaders()); + + } + + private void addRequestContext(String uri, MultivaluedMap<String, String> requestHeaders) { + + String rc = ""; + + Matcher match = versionedEndpoint.matcher(uri); + if (match.find()) { + rc = match.group(1); + } + + if (requestHeaders.containsKey(AAIHeaderProperties.REQUEST_CONTEXT)) { + requestHeaders.remove(AAIHeaderProperties.REQUEST_CONTEXT); + } + requestHeaders.put(AAIHeaderProperties.REQUEST_CONTEXT, Collections.singletonList(rc)); + } + +} diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/RequestModification.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/RequestModification.java new file mode 100644 index 0000000..a5f8789 --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/RequestModification.java @@ -0,0 +1,77 @@ +/*- + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.aai.interceptors.pre; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.annotation.Priority; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.container.PreMatching; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.UriBuilder; + +import org.onap.aai.interceptors.AAIContainerFilter; + +@PreMatching +@Priority(AAIRequestFilterPriority.HEADER_VALIDATION) +public class RequestModification extends AAIContainerFilter implements ContainerRequestFilter { + + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + + this.cleanDME2QueryParams(requestContext); + + } + + private void cleanDME2QueryParams(ContainerRequestContext request) { + UriBuilder builder = request.getUriInfo().getRequestUriBuilder(); + MultivaluedMap<String, String> queries = request.getUriInfo().getQueryParameters(); + + String[] blacklist = { "version", "envContext", "routeOffer" }; + Set<String> blacklistSet = Arrays.stream(blacklist).collect(Collectors.toSet()); + + boolean remove = true; + + for (String param : blacklistSet) { + if (!queries.containsKey(param)) { + remove = false; + break; + } + } + + if (remove) { + for (Map.Entry<String, List<String>> query : queries.entrySet()) { + String key = query.getKey(); + if (blacklistSet.contains(key)) { + builder.replaceQueryParam(key); + } + } + } + request.setRequestUri(builder.build()); + } + +} diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/RequestTransactionLogging.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/RequestTransactionLogging.java new file mode 100644 index 0000000..83d89ae --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/RequestTransactionLogging.java @@ -0,0 +1,113 @@ +/*- + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.aai.interceptors.pre; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Random; +import java.util.UUID; + +import javax.annotation.Priority; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.container.PreMatching; +import javax.ws.rs.core.MediaType; + +import org.glassfish.jersey.message.internal.ReaderWriter; +import org.glassfish.jersey.server.ContainerException; +import org.onap.aai.exceptions.AAIException; +import org.onap.aai.interceptors.AAIContainerFilter; +import org.onap.aai.interceptors.AAIHeaderProperties; +import org.onap.aai.util.AAIConfig; +import org.onap.aai.util.AAIConstants; +import org.onap.aai.util.HbaseSaltPrefixer; +import org.springframework.beans.factory.annotation.Autowired; + +import com.google.gson.JsonObject; + +@PreMatching +@Priority(AAIRequestFilterPriority.REQUEST_TRANS_LOGGING) +public class RequestTransactionLogging extends AAIContainerFilter implements ContainerRequestFilter { + + @Autowired + private HttpServletRequest httpServletRequest; + + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + + String currentTimeStamp = genDate(); + String fullId = this.getAAITxIdToHeader(currentTimeStamp); + this.addToRequestContext(requestContext, AAIHeaderProperties.AAI_TX_ID, fullId); + this.addToRequestContext(requestContext, AAIHeaderProperties.AAI_REQUEST, this.getRequest(requestContext, fullId)); + this.addToRequestContext(requestContext, AAIHeaderProperties.AAI_REQUEST_TS, currentTimeStamp); + } + + private void addToRequestContext(ContainerRequestContext requestContext, String name, String aaiTxIdToHeader) { + requestContext.setProperty(name, aaiTxIdToHeader); + } + + private String getAAITxIdToHeader(String currentTimeStamp) { + String txId = UUID.randomUUID().toString(); + try { + txId = HbaseSaltPrefixer.getInstance().prependSalt(AAIConfig.get(AAIConstants.AAI_NODENAME) + "-" + + currentTimeStamp + "-" + new Random(System.currentTimeMillis()).nextInt(99999)); + } catch (AAIException e) { + } + + return txId; + } + + private String getRequest(ContainerRequestContext requestContext, String fullId) { + + JsonObject request = new JsonObject(); + request.addProperty("ID", fullId); + request.addProperty("Http-Method", requestContext.getMethod()); + String contentType = httpServletRequest.getContentType(); + + if(contentType == null){ + contentType = MediaType.APPLICATION_JSON; + requestContext.getHeaders().add("Content-Type", contentType); + } + + request.addProperty("Content-Type", contentType); + request.addProperty("Headers", requestContext.getHeaders().toString()); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + InputStream in = requestContext.getEntityStream(); + + try { + if (in.available() > 0) { + ReaderWriter.writeTo(in, out); + byte[] requestEntity = out.toByteArray(); + request.addProperty("Payload", new String(requestEntity, "UTF-8")); + requestContext.setEntityStream(new ByteArrayInputStream(requestEntity)); + } + } catch (IOException ex) { + throw new ContainerException(ex); + } + + return request.toString(); + } + +} diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/SetLoggingContext.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/SetLoggingContext.java new file mode 100644 index 0000000..76de206 --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/SetLoggingContext.java @@ -0,0 +1,70 @@ +/*- + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.aai.interceptors.pre; + +import java.io.IOException; + +import javax.annotation.Priority; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.container.PreMatching; + +import org.onap.aai.interceptors.AAIContainerFilter; +import org.onap.aai.interceptors.AAIHeaderProperties; +import org.onap.aai.logging.LoggingContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; + +@PreMatching +@Priority(AAIRequestFilterPriority.SET_LOGGING_CONTEXT) +public class SetLoggingContext extends AAIContainerFilter implements ContainerRequestFilter { + + @Autowired + private Environment environment; + + @Autowired + private HttpServletRequest httpServletRequest; + + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + + String uri = httpServletRequest.getRequestURI(); + String queryString = httpServletRequest.getQueryString(); + + if(queryString != null && !queryString.isEmpty()){ + uri = uri + "?" + queryString; + } + + String httpMethod = requestContext.getMethod(); + String transId = requestContext.getHeaderString(AAIHeaderProperties.TRANSACTION_ID); + String fromAppId = requestContext.getHeaderString(AAIHeaderProperties.FROM_APP_ID); + + LoggingContext.init(); + LoggingContext.requestId(transId); + LoggingContext.partnerName(fromAppId); + LoggingContext.targetEntity(environment.getProperty("spring.application.name")); + LoggingContext.component(fromAppId); + LoggingContext.serviceName(httpMethod + " " + uri); + LoggingContext.targetServiceName(httpMethod + " " + uri); + } + +} diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/retired/RetiredConsumer.java b/aai-traversal/src/main/java/org/onap/aai/rest/retired/RetiredConsumer.java index 0188142..301fa5c 100644 --- a/aai-traversal/src/main/java/org/onap/aai/rest/retired/RetiredConsumer.java +++ b/aai-traversal/src/main/java/org/onap/aai/rest/retired/RetiredConsumer.java @@ -35,7 +35,7 @@ import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; -import org.apache.cxf.jaxrs.ext.PATCH; +import io.swagger.jaxrs.PATCH; import org.onap.aai.exceptions.AAIException; import org.onap.aai.logging.ErrorLogHelper; diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/util/EchoResponse.java b/aai-traversal/src/main/java/org/onap/aai/rest/util/EchoResponse.java index 55a07e4..1dfc99f 100644 --- a/aai-traversal/src/main/java/org/onap/aai/rest/util/EchoResponse.java +++ b/aai-traversal/src/main/java/org/onap/aai/rest/util/EchoResponse.java @@ -42,11 +42,12 @@ import org.onap.aai.restcore.RESTAPI; /** * The Class EchoResponse. */ +@Path("/util") public class EchoResponse extends RESTAPI { protected static String authPolicyFunctionName = "util"; - public static final String echoPath = "/util/echo"; + public static final String echoPath = "/echo"; /** * Simple health-check API that echos back the X-FromAppId and X-TransactionId to clients. diff --git a/aai-traversal/src/main/java/org/onap/aai/web/JerseyConfiguration.java b/aai-traversal/src/main/java/org/onap/aai/web/JerseyConfiguration.java new file mode 100644 index 0000000..96fd2a2 --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/web/JerseyConfiguration.java @@ -0,0 +1,127 @@ +package org.onap.aai.web; + +import org.glassfish.jersey.filter.LoggingFilter; +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.servlet.ServletProperties; +import org.onap.aai.rest.QueryConsumer; +import org.onap.aai.rest.retired.V3ThroughV7Consumer; +import org.onap.aai.rest.search.ModelAndNamedQueryRestProvider; +import org.onap.aai.rest.search.SearchProvider; +import org.onap.aai.rest.util.EchoResponse; +import org.reflections.Reflections; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +import javax.annotation.Priority; +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.container.ContainerResponseFilter; +import java.util.List; +import java.util.Set; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +@Component +@ApplicationPath("/aai") +public class JerseyConfiguration extends ResourceConfig { + + private static final Logger log = Logger.getLogger(JerseyConfiguration.class.getName()); + + private Environment env; + + @Autowired + public JerseyConfiguration(Environment env) { + + this.env = env; + + register(SearchProvider.class); + register(ModelAndNamedQueryRestProvider.class); + register(QueryConsumer.class); + + register(V3ThroughV7Consumer.class); + register(EchoResponse.class); + + //Request Filters + registerFiltersForRequests(); + // Response Filters + registerFiltersForResponses(); + + property(ServletProperties.FILTER_FORWARD_ON_404, true); + + // Following registers the request headers and response headers + // If the LoggingFilter second argument is set to true, it will print response value as well + if ("true".equalsIgnoreCase(env.getProperty("aai.request.logging.enabled"))) { + register(new LoggingFilter(log, false)); + } + } + + public void registerFiltersForRequests() { + + // Find all the classes within the interceptors package + Reflections reflections = new Reflections("org.onap.aai.interceptors"); + // Filter them based on the clazz that was passed in + Set<Class<? extends ContainerRequestFilter>> filters = reflections.getSubTypesOf(ContainerRequestFilter.class); + + + // Check to ensure that each of the filter has the @Priority annotation and if not throw exception + for (Class filterClass : filters) { + if (filterClass.getAnnotation(Priority.class) == null) { + throw new RuntimeException("Container filter " + filterClass.getName() + " does not have @Priority annotation"); + } + } + + // Turn the set back into a list + List<Class<? extends ContainerRequestFilter>> filtersList = filters + .stream() + .filter(f -> { + if (f.isAnnotationPresent(Profile.class) + && !env.acceptsProfiles(f.getAnnotation(Profile.class).value())) { + return false; + } + return true; + }) + .collect(Collectors.toList()); + + // Sort them by their priority levels value + filtersList.sort((c1, c2) -> Integer.valueOf(c1.getAnnotation(Priority.class).value()).compareTo(c2.getAnnotation(Priority.class).value())); + + // Then register this to the jersey application + filtersList.forEach(this::register); + } + + public void registerFiltersForResponses() { + + // Find all the classes within the interceptors package + Reflections reflections = new Reflections("org.onap.aai.interceptors"); + // Filter them based on the clazz that was passed in + Set<Class<? extends ContainerResponseFilter>> filters = reflections.getSubTypesOf(ContainerResponseFilter.class); + + + // Check to ensure that each of the filter has the @Priority annotation and if not throw exception + for (Class filterClass : filters) { + if (filterClass.getAnnotation(Priority.class) == null) { + throw new RuntimeException("Container filter " + filterClass.getName() + " does not have @Priority annotation"); + } + } + + // Turn the set back into a list + List<Class<? extends ContainerResponseFilter>> filtersList = filters.stream() + .filter(f -> { + if (f.isAnnotationPresent(Profile.class) + && !env.acceptsProfiles(f.getAnnotation(Profile.class).value())) { + return false; + } + return true; + }) + .collect(Collectors.toList()); + + // Sort them by their priority levels value + filtersList.sort((c1, c2) -> Integer.valueOf(c1.getAnnotation(Priority.class).value()).compareTo(c2.getAnnotation(Priority.class).value())); + + // Then register this to the jersey application + filtersList.forEach(this::register); + } + +} diff --git a/aai-traversal/src/main/java/org/onap/aai/web/LocalHostAccessLog.java b/aai-traversal/src/main/java/org/onap/aai/web/LocalHostAccessLog.java new file mode 100644 index 0000000..4344e36 --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/web/LocalHostAccessLog.java @@ -0,0 +1,39 @@ +package org.onap.aai.web; + +import ch.qos.logback.access.jetty.RequestLogImpl; +import org.eclipse.jetty.server.handler.HandlerCollection; +import org.eclipse.jetty.server.handler.RequestLogHandler; +import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; +import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory; +import org.springframework.boot.context.embedded.jetty.JettyServerCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Arrays; + +@Configuration +public class LocalHostAccessLog { + + @Bean + public EmbeddedServletContainerFactory jettyConfigBean(){ + JettyEmbeddedServletContainerFactory jef = new JettyEmbeddedServletContainerFactory(); + jef.addServerCustomizers((JettyServerCustomizer) server -> { + + HandlerCollection handlers = new HandlerCollection(); + + Arrays.stream(server.getHandlers()).forEach(handlers::addHandler); + + RequestLogHandler requestLogHandler = new RequestLogHandler(); + requestLogHandler.setServer(server); + + RequestLogImpl requestLogImpl = new RequestLogImpl(); + requestLogImpl.setResource("/localhost-access-logback.xml"); + requestLogImpl.start(); + + requestLogHandler.setRequestLog(requestLogImpl); + handlers.addHandler(requestLogHandler); + server.setHandler(handlers); + }); + return jef; + } +} diff --git a/aai-traversal/src/main/java/org/onap/aai/web/WebConfiguration.java b/aai-traversal/src/main/java/org/onap/aai/web/WebConfiguration.java new file mode 100644 index 0000000..a85fcf9 --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/web/WebConfiguration.java @@ -0,0 +1,27 @@ +package org.onap.aai.web; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +@Configuration +public class WebConfiguration { + + @Bean + public WebMvcConfigurerAdapter forwardToIndex() { + return new WebMvcConfigurerAdapter() { + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/swagger").setViewName( + "redirect:/swagger/index.html"); + registry.addViewController("/swagger/").setViewName( + "redirect:/swagger/index.html"); + registry.addViewController("/docs").setViewName( + "redirect:/docs/html/index.html"); + registry.addViewController("/docs/").setViewName( + "redirect:/docs/html/index.html"); + } + }; + } +}
\ No newline at end of file |