diff options
Diffstat (limited to 'ms/neng/src')
9 files changed, 1066 insertions, 0 deletions
diff --git a/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/Application.java b/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/Application.java new file mode 100644 index 00000000..e95fb7eb --- /dev/null +++ b/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/Application.java @@ -0,0 +1,77 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK.apps + * ================================================================================ + * Copyright (C) 2018 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.ccsdk.apps.ms.neng.core; + +import java.util.Arrays; +import org.springframework.boot.CommandLineRunner; +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.orm.jpa.HibernateJpaAutoConfiguration; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.scheduling.annotation.EnableAsync; + +/** + * Entry point for the micro-service -- it starts up the application. + */ +@SpringBootApplication +@ComponentScan(basePackages = "org.onap.ccsdk") +@EnableAsync +@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class}) +public class Application extends SpringBootServletInitializer { + /** + * Configures the application. + */ + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(Application.class); + } + + /** + * Entry point for the application. + */ + public static void main(String[] args) throws Exception { + SpringApplication.run(Application.class, args); + } + + /** + * Prints diagnostic information after application startup. + */ + @Bean + public CommandLineRunner commandLineRunner(ApplicationContext ctx) { + return args -> { + System.out.println("################################"); + System.out.println("Inspecting the beans provided by Spring Boot:"); + String[] beanNames = ctx.getBeanDefinitionNames(); + Arrays.sort(beanNames); + for (String beanName : beanNames) { + System.out.println(beanName); + } + System.out.println("################################"); + }; + } + +} diff --git a/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/persistence/ApplicationConfig.java b/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/persistence/ApplicationConfig.java new file mode 100644 index 00000000..d69c270c --- /dev/null +++ b/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/persistence/ApplicationConfig.java @@ -0,0 +1,141 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK.apps + * ================================================================================ + * Copyright (C) 2018 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.ccsdk.apps.ms.neng.core.persistence; + +import java.util.HashMap; +import java.util.Map; +import javax.sql.DataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.JpaVendorAdapter; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +/** + * Manages the overall configuration of the application related to persistence. + */ +@Configuration +@EnableJpaRepositories(basePackages = "org.onap.ccsdk.apps.ms.neng.persistence.repository") +@EnableTransactionManagement +public class ApplicationConfig { + + @Autowired + private Environment environment; + + /** + * Builds and returns the DataSource used for persisting the data managed by this micro-service. + */ + @Bean + public DataSource dataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName(environment.getProperty("datasource.db.driver-class-name")); + dataSource.setUrl(environment.getProperty("datasource.db.url")); + dataSource.setUsername(environment.getProperty("datasource.db.username")); + dataSource.setPassword(environment.getProperty("datasource.db.password")); + return dataSource; + } + + /** + * Builds and returns the JpaProperties used for configuration. + */ + @Bean + @ConfigurationProperties(prefix = "jpa") + public JpaProperties jpaProperties() { + return new JpaProperties(); + } + + /** + * Builds and returns the JpaVendorAdapter used for configuration. + */ + @Bean + public JpaVendorAdapter jpaVendorAdapter(JpaProperties jpaProperties) { + HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter(); + hibernateJpaVendorAdapter.setShowSql(jpaProperties.isShowSql()); + hibernateJpaVendorAdapter.setGenerateDdl(jpaProperties.isGenerateDdl()); + return hibernateJpaVendorAdapter; + } + + /** + * Builds and returns the Properties used for Hibernate configuration. + */ + @Bean + public Map<String, String> hibProperties() { + Map<String, String> hibProperties = new HashMap<>(); + String[] propertyNames = { + "hibernate.dialect", + "hibernate.show_sql", + "hibernate.format_sql", + "hibernate.cache.provider_class", + "hibernate.id.new_generator_mappings", + "hibernate.hbm2ddl.auto", + }; + for (String name : propertyNames) { + hibProperties.put(name, environment.getProperty(name)); + } + return hibProperties; + } + + /** + * Builds and returns the JpaTransactionManager. + */ + @Bean + public JpaTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean entityManagerFactory) { + JpaTransactionManager transactionManager = new JpaTransactionManager(); + transactionManager.setEntityManagerFactory(entityManagerFactory.getObject()); + return transactionManager; + } + + /** + * Builds and returns the PersistenceExceptionTranslationPostProcessor. + * + * <p/>PersistenceExceptionTranslationPostProcessor is a bean post processor which adds an advisor to any bean + * annotated with Repository so that any platform-specific exceptions are caught and then re-thrown + * as one of Spring's unchecked data access exceptions (i.e. a subclass of DataAccessException). + */ + @Bean + public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { + return new PersistenceExceptionTranslationPostProcessor(); + } + + /** + * Builds and returns the Factory used for building entities. + */ + @Bean + public LocalContainerEntityManagerFactoryBean entityManagerFactory( + JpaVendorAdapter jpaVendAdapter, + Map<String, String> hibProps, + DataSource dataSource) { + EntityManagerFactoryBuilder factBuilder = new EntityManagerFactoryBuilder(jpaVendAdapter, hibProps, null); + String pkgToScan = environment.getProperty("entitymanager.packagesToScan"); + return factBuilder.dataSource(dataSource).packages(pkgToScan).build(); + } + +} diff --git a/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/policy/PolicyFinder.java b/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/policy/PolicyFinder.java new file mode 100644 index 00000000..6d8a27a7 --- /dev/null +++ b/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/policy/PolicyFinder.java @@ -0,0 +1,38 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK.apps + * ================================================================================ + * Copyright (C) 2018 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.ccsdk.apps.ms.neng.core.policy; + +import java.util.Map; + +/** + * Finds policy data, normally by calling policy-manager. + */ +public interface PolicyFinder { + /** + * Finds the policy with a given name. + * + * @param policyName the name of the policy the caller is looking for + * @return a map ( String -> Object ) representing the policy, as a general JSON structure, + * where the map entries are String-s, or arrays of similar maps, or similar nested maps. + * @throws Exception any exceptions caught are propagated + */ + public Map<String, Object> findPolicy(String policyName) throws Exception; +} diff --git a/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/policy/PolicyParameters.java b/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/policy/PolicyParameters.java new file mode 100644 index 00000000..37fc38cb --- /dev/null +++ b/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/policy/PolicyParameters.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK.apps + * ================================================================================ + * Copyright (C) 2018 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.ccsdk.apps.ms.neng.core.policy; + +/** + * Specifies parameters that control the nature of policy data and the behavior of this micro-service. + * + * <p/>These parameters are typically stored in DB or read from a configuration file. + */ +public interface PolicyParameters { + /** + * Gives the separator between the entries within the same recipe -- such as the pipe('|') character. + */ + public String getRecipeSeparator() throws Exception; + + /** + * Maps a given function, used in the policy, to the equivalent function in this micro-service. + */ + public String mapFunction(String name) throws Exception; + + /** + * Maximum number of times the micro-service should attempt name generation in the same transaction + * (if all previous attempts in the same transaction fail). + */ + public int getMaxGenAttempt() throws Exception; +} diff --git a/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/policy/PolicyPropertyMethodUtils.java b/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/policy/PolicyPropertyMethodUtils.java new file mode 100644 index 00000000..9f4725fb --- /dev/null +++ b/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/policy/PolicyPropertyMethodUtils.java @@ -0,0 +1,69 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK.apps + * ================================================================================ + * Copyright (C) 2018 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.ccsdk.apps.ms.neng.core.policy; + +/** + * Utility methods equivalent to the JavaScript like functions used in policies by the policy-manager. + */ +public class PolicyPropertyMethodUtils { + + /** + * Equivalent to the substring function used by policy-manager (which works similar to JavaScript + * substring function). + */ + public static String substring(String sourceStr, String startIndex, String endIndex) { + return sourceStr.substring(Integer.parseInt(startIndex), Integer.parseInt(endIndex)); + } + + /** + * Equivalent to the substring function used by policy-manager (which works similar to JavaScript + * substring function). + */ + public static String substring(String sourceStr, String length) { + + int startIndexInt = 0; + int subStrLength = Integer.parseInt(length); + if (subStrLength < 0) { + + startIndexInt = sourceStr.length() + subStrLength; + startIndexInt = (startIndexInt < 0) ? 0 : startIndexInt; + + return sourceStr.substring(startIndexInt); + } else if (subStrLength > sourceStr.length()) { + subStrLength = sourceStr.length(); + } + return sourceStr.substring(startIndexInt, subStrLength); + } + + /** + * Equivalent to the to_upper_case function used by policy-manager. + */ + public static String toUpperCase(String sourceStr) { + return sourceStr.toUpperCase(); + } + + /** + * Equivalent to the to_lower_case function used by policy-manager. + */ + public static String toLowerCase(String sourceStr) { + return sourceStr.toLowerCase(); + } +} diff --git a/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/policy/PolicyReader.java b/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/policy/PolicyReader.java new file mode 100644 index 00000000..de034f04 --- /dev/null +++ b/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/policy/PolicyReader.java @@ -0,0 +1,328 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK.apps + * ================================================================================ + * Copyright (C) 2018 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.ccsdk.apps.ms.neng.core.policy; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Converts policy data to the structure expected by this micro-service. + */ +public abstract class PolicyReader implements PolicyFinder { + /** + * Extracts the naming-models from a policy. + * + * @param policy the policy + * @return the list of naming-models found in the policy + */ + public static List<Map<String, ?>> namingModels(Map<String, ?> policy) { + Set<String> keys = policy.keySet(); + // TODO : retrieve naming-models at any level + if (keys.contains("config")) { + @SuppressWarnings("unchecked") + Map<String, ?> config = (Map<String, ?>) policy.get("config"); + List<Map<String, ?>> namingModels = list(map(config, "content"), "naming-models"); + if (namingModels == null) { + namingModels = list(config, "naming-models"); + } + return namingModels; + } else { + return list(map(map(policy, "input"), "naming-model"), "naming-models"); + } + + } + + /** + * Extracts a naming-model from the given list of models, based on a naming-type. + * + * @param namingModels a list of naming-models + * @param namingType the naming type + * @return the naming model found, or null if none is found + */ + public static Map<String, ?> namingModel(List<Map<String, ?>> namingModels, String namingType) { + Map<String, ?> theModel = null; + if (namingModels != null) { + for (Map<String, ?> model : namingModels) { + Object val = model.get("naming-type"); + if (namingType.equals(val)) { + theModel = model; + break; + } + } + } + return theModel; + } + + /** + * Extracts a naming-model from the given list of models, based on a naming-type, by using a more + * relaxed/liberal comparison of the naming-type. + * + * <p/>When doing the relaxed comparison, upper-case/lower-case differences are ignored, some + * special characters like underscore, dash etc. are ignored, and the presence of the 'NAME' + * at the end of the naming-type is ignored. + * + * @param namingModels a list of naming-models + * @param namingType the naming type + * @return the naming model found, or null if none is found + */ + public static Map<String, ?> namingModelRelaxed(List<Map<String, ?>> namingModels, String namingType) { + Map<String, ?> theModel = null; + if (namingModels != null) { + for (Map<String, ?> model : namingModels) { + Object val = model.get("naming-type"); + if (val != null) { + if (namingType.equalsIgnoreCase(val.toString())) { + theModel = model; + break; + } + } + } + if (theModel == null) { + namingType = relaxedNamingType(namingType); + for (Map<String, ?> model : namingModels) { + Object val = model.get("naming-type"); + if (val != null) { + String relaxedVal = relaxedNamingType(val.toString()); + if (namingType.equalsIgnoreCase(relaxedVal)) { + theModel = model; + break; + } + } + } + } + } + return theModel; + } + + /** + * Finds the naming-operation from the given naming-model. + */ + public static String namingOperation(Map<String, ?> namimgModel) { + String propValue = value(namimgModel, "name-operation"); + return propValue; + } + + /** + * Finds the naming-property with a given name from a naming-model. + * + * @param namingModel a naming-model + * @param propertyName the property name + * @return the property found, or null if none is found + */ + public static Map<String, ?> namingProperty(Map<String, ?> namingModel, String propertyName) { + List<Map<String, ?>> properties = namingProperties(namingModel); + Map<String, ?> theProp = null; + if (properties != null) { + for (Map<String, ?> prop : properties) { + String onePropName = propertyName(prop); + if (propertyName.equals(onePropName)) { + theProp = prop; + break; + } + } + } + return theProp; + } + + /** + * Finds the naming-recipe from the given naming-model. + */ + public static String namingRecipe(Map<String, ?> namimgModel) { + return value(namimgModel, "naming-recipe"); + } + + /** + * Finds the naming-type from the given naming-model. + */ + public static String namingType(Map<String, ?> namimgModelOrElement) { + return value(namimgModelOrElement, "naming-type"); + } + + /** + * Finds the property-value from the given property map. + */ + public static String propertyValue(Map<String, ?> properties) { + return value(properties, "property-value"); + } + + /** + * Converts the a naming-type to a relaxed/liberal convention. + * + * <p/>In the relaxed convention, all characters are upper-case, some special characters like underscore, + * dash etc. are ignored, and there is no 'NAME' at the end of the naming-type. + * + * @param type the naming-type + */ + public static String relaxedNamingType(String type) { + type = type.toUpperCase(); + if (type.endsWith("NAME")) { + type = type.substring(0, type.length() - 4); + } + type = type.replaceAll("-", ""); + type = type.replaceAll("_", ""); + return type; + } + + /** + * Builds a PolicySequence based on given properties. + */ + public static PolicySequence seq(Map<String, ?> properties) { + properties = map(properties, "increment-sequence"); + String scope = value(properties, "scope"); + String startValue = value(properties, "start-value"); + String max = value(properties, "max"); + String increment = value(properties, "increment"); + String type = value(properties, "sequence-type"); + String length = value(properties, "length"); + + PolicySequence seq = new PolicySequence(); + seq.setScope(scope); + seq.setStartValue(number(startValue, 1)); + seq.setMaxValueString(max); + seq.setIncrement(number(increment, 1)); + seq.setType(type); + seq.setLength(number(length, 3)); + + return seq; + } + + /** + * Finds the value of a given key, as a String, in a map. + * + * @param map a map, which can be null + * @param key a key + * @return the value of the key in the map, or null if there is none. + */ + public static String value(Map<String, ?> map, String key) { + String value = null; + if (map != null) { + value = (String) map.get(key); + if (!(value instanceof String)) { + value = null; + } + } + return value; + } + + /** + * Finds the value of a given key, as a String, in a map. + * + * @param map a map, which can be null + * @param key a key + * @param relaxed if true, relaxed/liberal comparison of the keys is done, by ignoring special + * characters dash and underscore + * @return the value of the key in the map, or null if there is none. + */ + public static String value(Map<String, ?> map, String key, boolean relaxed) { + if (relaxed) { + String value = null; + if (map != null) { + for (final String aKey : map.keySet()) { + if (aKey.equalsIgnoreCase(key)) { + value = (String) map.get(aKey); + break; + } + } + if (value == null) { + key = key.replaceAll("_", ""); + key = key.replaceAll("-", ""); + for (final String aKey : map.keySet()) { + String keyDup = aKey.replaceAll("_", ""); + keyDup = keyDup.replaceAll("-", ""); + if (keyDup.equalsIgnoreCase(key)) { + value = (String) map.get(aKey); + break; + } + } + } + if (!(value instanceof String)) { + value = null; + } + } + return value; + } else { + return value(map, key); + } + } + + static Map<String, ?> dependentNamingModel(List<Map<String, ?>> namingModels, String recipeItem) { + Map<String, ?> theModel = namingModel(namingModels, recipeItem); + if (theModel == null) { + theModel = namingModelRelaxed(namingModels, recipeItem); + } + return theModel; + } + + Map<String, Object> getPolicy(String jsonString) throws Exception { + ObjectMapper mapper = new ObjectMapper(); + Map<String, Object> jsonObject = mapper.readValue(jsonString, new TypeReference<Map<String, Object>>() {}); + return jsonObject; + } + + static List<Map<String, ?>> list(Map<String, ?> policy, String name) { + List<Map<String, ?>> list = null; + if (policy != null) { + @SuppressWarnings("unchecked") + List<Map<String, ?>> listObj = (List<Map<String, ?>>) policy.get(name); + if (list instanceof List<?>) { + list = listObj; + } + } + return list; + } + + static Map<String, ?> map(Map<String, ?> policy, String name) { + Map<String, ?> map = null; + if (policy != null) { + @SuppressWarnings("unchecked") + Map<String, ?> mapObj = (Map<String, ?>) policy.get(name); + if (mapObj instanceof Map<?, ?>) { + map = mapObj; + } + } + return map; + } + + static List<Map<String, ?>> namingProperties(Map<String, ?> namimgModel) { + return list(namimgModel, "naming-properties"); + } + + static long number(String str, long defaultValue) { + long value; + try { + value = Long.valueOf(str); + } catch (Exception e) { + value = defaultValue; + } + return value; + } + + static String propertyName(Map<String, ?> properties) { + return value(properties, "property-name"); + } + + static String propertyOperation(Map<String, ?> properties) { + return value(properties, "property-operation"); + } +} diff --git a/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/policy/PolicySequence.java b/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/policy/PolicySequence.java new file mode 100644 index 00000000..dc0b6fdc --- /dev/null +++ b/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/policy/PolicySequence.java @@ -0,0 +1,158 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK.apps + * ================================================================================ + * Copyright (C) 2018 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.ccsdk.apps.ms.neng.core.policy; + +/** + * Represents a sequence object in the policy, as a POJO. + */ +public class PolicySequence { + /** + * The type of the policy sequence. + */ + public enum Type { + ALPHA, NUMERIC + } + + private long startValue; + private long increment; + private long length; + private Long maxValue; + private String maxValueString; + private Type type = Type.NUMERIC; + private String scope; + private String key; + private String value; + private Long lastReleaseSeqNumTried; + + public long getStartValue() { + return startValue; + } + + public void setStartValue(long startValue) { + this.startValue = startValue; + } + + public long getIncrement() { + return increment; + } + + public void setIncrement(long increment) { + this.increment = increment; + } + + public long getLength() { + return length; + } + + public void setLength(long length) { + this.length = length; + } + + /** + * Generate and return the maximum value for the sequence. + */ + public long getMaxValue() { + if (this.maxValue == null) { + int base = 10; + if (this.type == Type.ALPHA) { + base = 36; + } + if (this.maxValueString != null) { + try { + this.maxValue = Long.valueOf(this.maxValueString, base); + } catch (Exception e) { + this.maxValue = null; + } + } + if (this.maxValue == null) { + long length = this.length; + if (length <= 0) { + length = 3; + } + this.maxValue = (long) Math.pow(base, length) - 1; + } + } + return maxValue; + } + + public void setMaxValue(long maxValue) { + this.maxValue = maxValue; + } + + public String getMaxValueString() { + return maxValueString; + } + + public void setMaxValueString(String maxValueString) { + this.maxValueString = maxValueString; + } + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + /** + * Sets the type. + */ + public void setType(String typeStr) { + if ("numeric".equalsIgnoreCase(typeStr)) { + setType(Type.NUMERIC); + } else if ("alpha-numeric".equalsIgnoreCase(typeStr)) { + setType(Type.ALPHA); + } + } + + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public Long getLastReleaseSeqNumTried() { + return lastReleaseSeqNumTried; + } + + public void setLastReleaseSeqNumTried(Long lastReleaseSeqNumTried) { + this.lastReleaseSeqNumTried = lastReleaseSeqNumTried; + } +} diff --git a/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/policy/PropertyOperator.java b/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/policy/PropertyOperator.java new file mode 100644 index 00000000..7eb63244 --- /dev/null +++ b/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/policy/PropertyOperator.java @@ -0,0 +1,152 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK.apps + * ================================================================================ + * Copyright (C) 2018 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.ccsdk.apps.ms.neng.core.policy; + +import static org.onap.ccsdk.apps.ms.neng.core.policy.PolicyReader.propertyOperation; + +import java.lang.reflect.Method; +import java.util.Map; + +/** + * Applies property operations while processing a policy. + */ +public class PropertyOperator { + /** + * Apply a property found in the policy. + * + * <p/> If the property cannot be applied correctly for any reason, the value is returned as is. + * + * @param value the String to which the property has to be applied + * @param propertyMap a map representing the property, the key of which is "property-operation" + * and the value is the actual property + * @param policyParams parameters configuring policy + * @return the result of applying the property + * @throws Exception all exceptions are propagated + */ + public String apply(String value, Map<String, ?> propertyMap, PolicyParameters policyParams) throws Exception { + String op = propertyOperation(propertyMap); + String mapped = null; + if (op != null) { + String fn = operationFunction(op); + if (fn != null) { + mapped = policyParams.mapFunction(fn); + if (mapped == null) { + mapped = camelConverted(fn); + } + if (mapped != null) { + op = op.replaceFirst(fn, mapped); + } + } + value = applyJavaOperation(value, op, mapped); + } + return value; + } + + /** + * Apply a property found in the policy. + * + * <p/> If the property cannot be applied correctly for any reason, the value is returned as is. + * + * @param value the String to which the property has to be applied + * @param operation the operation to be applied + * @param policyParams parameters configuring policy + * @return the result of applying the property + * @throws Exception all exceptions are propagated + */ + public String apply(String value, String operation, PolicyParameters policyParams) throws Exception { + String mapped = null; + if (operation != null) { + String fn = operationFunction(operation); + if (fn != null) { + mapped = policyParams.mapFunction(fn); + if (mapped == null) { + mapped = camelConverted(fn); + } + if (mapped != null) { + operation = operation.replaceFirst(fn, mapped); + } + } + value = applyJavaOperation(value, operation, mapped); + } + return value; + } + + private String applyJavaOperation(String inputString, String op, String methodName) throws Exception { + String postOp = null; + try { + String argPart = ""; + if (op.indexOf("(") > 0) { + int funcStartIndex = op.indexOf("("); + int funcEndIndex = op.lastIndexOf(")"); + argPart = op.substring(funcStartIndex + 1, funcEndIndex); + } + + argPart = inputString + "," + argPart; + String[] args = argPart.split(","); + + PolicyPropertyMethodUtils utils = new PolicyPropertyMethodUtils(); + for (Method m : PolicyPropertyMethodUtils.class.getDeclaredMethods()) { + if (m.getName().equals(methodName) && m.getParameterCount() == args.length) { + postOp = (String) m.invoke(utils, (Object[])args); + break; + } + } + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + return postOp; + } + + static String operationFunction(String operation) throws Exception { + operation = operation.trim(); + int i = 0; + for (; i < operation.length(); ++i) { + char ch = operation.charAt(i); + if (!Character.isJavaIdentifierPart(ch)) { + break; + } + } + String value = operation.substring(0, i); + if (value.length() == 0) { + value = null; + } + return value; + } + + static String camelConverted(String fn) throws Exception { + boolean upperNext = false; + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < fn.length(); ++i) { + char ch = fn.charAt(i); + if (ch == '_') { + upperNext = true; + } else { + if (upperNext) { + ch = Character.toUpperCase(ch); + } + buf.append(ch); + upperNext = false; + } + } + return buf.toString(); + } +} diff --git a/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/policy/RecipeParser.java b/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/policy/RecipeParser.java new file mode 100644 index 00000000..d9eda66a --- /dev/null +++ b/ms/neng/src/main/java/org/onap/ccsdk/apps/ms/neng/core/policy/RecipeParser.java @@ -0,0 +1,59 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK.apps + * ================================================================================ + * Copyright (C) 2018 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.ccsdk.apps.ms.neng.core.policy; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Parses recipe into a list of items. + */ +public class RecipeParser { + + /** + * Parses recipe into a list of items. + * + * @param policyParams the policy parameters + * @param recipe the recipe from policy manager + * @return a list containing the items in the recipe + * @throws Exception all exceptions are propagated + */ + public static List<String> parseRecipe(PolicyParameters policyParams, String recipe) throws Exception { + String separatorAll = policyParams.getRecipeSeparator(); + if (separatorAll == null) { + separatorAll = "|\":\","; + } + String[] separators = separatorAll.split("\""); + List<String> recipeItems = new ArrayList<>(); + for (String separator : separators) { + if (recipe.contains(separator)) { + separator = "\\" + separator; + recipeItems = Arrays.asList(recipe.split(separator)); + break; + } + } + if (recipeItems.isEmpty() && recipe.length() > 0) { + recipeItems.add(recipe); + } + return recipeItems; + } +} |