project_category: ''
lifecycle_state: 'Incubation'
project_lead: &onap_aai_ptl
- name: 'James Forsyth'
- email: 'jf2512@att.com'
- id: 'jimmydot'
+ name: 'William Reehil'
+ email: 'william.reehil@att.com'
company: 'ATT'
- timezone: 'America/Detroit'
+ id: 'wreehil'
+ timezone: 'America/New_York'
primary_contact: *onap_aai_ptl
issue_tracking:
type: 'jira'
repeats: 'weekly'
time: '14:00 UTC'
repositories:
- - 'aai-aai-common'
- - 'aai-aai-config'
- - 'aai-aai-data'
- - 'aai-aai-service'
- - 'aai-babel'
- - 'aai-cacher'
- - 'aai-chameleon'
- - 'aai-champ'
- - 'aai-data-router'
- - 'aai-eis'
- - 'aai-enricher'
- - 'aai-event-client'
- - 'aai-gallifrey'
- - 'aai-gap'
- - 'aai-gizmo'
- - 'aai-graphadmin'
- - 'aai-graphgraph'
- - 'aai-logging-service'
- - 'aai-model-loader'
- - 'aai-oom'
- - 'aai-resources'
- - 'aai-rest-client'
- - 'aai-router-core'
- - 'aai-schema-service'
- - 'aai-search-data-service'
- - 'aai-sparky-be'
- - 'aai-sparky-fe'
- - 'aai-spike'
- - 'aai-tabular-data-service'
- - 'aai-test-config'
- - 'aai-traversal'
- - 'aai-validation'
+ - 'aai/aai-common'
committers:
- <<: *onap_aai_ptl
- name: 'Manisha Aggarwal'
company: 'Amdocs'
id: 'sblimkie'
timezone: 'America/Toronto'
- - name: 'Tian Lee'
- email: 'TianL@amdocs.com'
- company: 'Amdocs'
- id: 'TianL'
- timezone: 'Europe/London'
- name: 'Venkata Harish Kajur'
email: 'vk250x@att.com'
company: 'ATT'
id: 'vk250x'
timezone: 'America/New_York'
+ - name: 'James Forsyth'
+ email: 'jf2512@att.com'
+ id: 'jimmydot'
+ company: 'ATT'
+ timezone: 'America/Detroit'
tsc:
- approval: 'https://lists.onap.org/pipermail/onap-tsc'
+ approval: 'https://lists.onap.org/g/onap-tsc'
changes:
- type: 'removal'
name: 'Steve Smokowski'
- link: 'https://lists.onap.org/pipermail/onap-tsc/2018-February/004361.html'
+ link: 'https://lists.onap.org/g/onap-tsc/message/2506'
+ - type: 'removal'
+ name: 'Tian Lee'
+ link: 'https://lists.onap.org/g/onap-tsc/message/6227'
+ - type: 'Addition'
+ name: 'William Reehil'
+ link: 'https://lists.onap.org/g/onap-tsc/message/6506'
--- /dev/null
+/*-
+ * ============LICENSE_START============================================
+ * ONAP Portal
+ * =====================================================================
+ * Copyright (C) 2020 IBM Intellectual Property. All rights reserved.
+ * =====================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.aaf.auth;
+
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import javax.servlet.http.HttpServletRequest;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.assertEquals;
+
+public class AafRequestWrapperTest {
+
+
+
+ @Test
+ public void testGetHeader(){
+ HttpServletRequest mockRequest = createMock(HttpServletRequest.class);
+ expect(mockRequest.getHeader(CertUtil.AAI_SSL_CLIENT_OU_HDR)).andReturn("m55555@org.onap.com:TEST").times(1, 4);
+ replay(mockRequest);
+ AafRequestWrapper af= new AafRequestWrapper(mockRequest);
+ assertEquals(af.getHeader("X-AAI-SSL-Client-OU"),"m55555@org.onap.com:TEST");
+ af.putHeader("X-AAI-SSL-Client-C","test@org.onap.com:test");
+ assertEquals(af.getHeader("X-AAI-SSL-Client-C"),"test@org.onap.com:test");
+ }
+}
--- /dev/null
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2020 IBM Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.aaf.filters;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.util.AAIConfig;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class CadiPropsTest {
+ @Autowired
+ CadiProps ca =new CadiProps("src/test/resources/bundleconfig-local/aaf/org.onap.aai.props");
+
+ @Test
+ public void testGetCadiFileName(){
+ assertEquals(ca.getCadiFileName(),"src/test/resources/bundleconfig-local/aaf/org.onap.aai.props");
+ assertNotNull(ca.getCadiProperties());
+ }
+}
RUN apk add --no-cache \
ca-certificates \
curl \
- openssl
+ openssl \
+ shadow \
+ util-linux && \
+ groupadd haproxy -g 1000 && \
+ adduser -u 1000 -S -D -G haproxy -s /bin/bash haproxy && \
+ chown -R haproxy:haproxy /usr/local/etc/haproxy
RUN mkdir -p /etc/ssl/certs/ && mkdir -p /etc/ssl/private
-COPY aai.pem /etc/ssl/private/aai.pem
-COPY docker-entrypoint.sh /docker-entrypoint.sh
-COPY resolvers.conf /usr/local/etc/haproxy/resolvers.conf
-COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg
+COPY --chown=haproxy aai.pem /etc/ssl/private/aai.pem
+COPY --chown=haproxy docker-entrypoint.sh /docker-entrypoint.sh
+COPY --chown=haproxy resolvers.conf /usr/local/etc/haproxy/resolvers.conf
+COPY --chown=haproxy haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg
RUN chmod +x /docker-entrypoint.sh
+USER haproxy
ENTRYPOINT [ "/docker-entrypoint.sh" ]
CMD [ "haproxy", "-f", "/usr/local/etc/haproxy/haproxy.cfg", "-f", "/usr/local/etc/haproxy/resolvers.conf" ]
if [ "$1" = 'haproxy' ]; then
# if the user wants "haproxy", let's use "haproxy-systemd-wrapper" instead so we can have proper reloadability implemented by upstream
shift # "haproxy"
- set -- "$(which haproxy-systemd-wrapper)" -p /run/haproxy.pid "$@"
+ set -- "$(which haproxy-systemd-wrapper)" -p /usr/local/etc/haproxy/haproxy.pid "$@"
fi
exec "$@"
log /dev/log local0
stats socket /usr/local/etc/haproxy/haproxy.socket mode 660 level admin
stats timeout 30s
- user root
- group root
daemon
#################################
# Default SSL material locations#
-/**
+/*
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
import com.google.common.collect.Multimap;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.janusgraph.core.Cardinality;
-import org.janusgraph.core.JanusGraph;
import org.janusgraph.core.Multiplicity;
import org.janusgraph.core.PropertyKey;
import org.janusgraph.core.schema.JanusGraphManagement;
import org.onap.aai.edges.EdgeRule;
import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException;
import org.onap.aai.introspection.Introspector;
-import org.onap.aai.introspection.Loader;
import org.onap.aai.introspection.LoaderUtil;
import org.onap.aai.logging.LogFormatTools;
import org.onap.aai.schema.enums.PropertyMetadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.*;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
public class SchemaGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(SchemaGenerator.class);
private SchemaGenerator() {
-
}
/**
* @param graphMgmt
* the graph mgmt
*/
- public static void loadSchemaIntoJanusGraph(final JanusGraphManagement graphMgmt,
- String backend) {
+ public static void loadSchemaIntoJanusGraph(final JanusGraphManagement graphMgmt, String backend) {
try {
AAIConfig.init();
} catch (Exception ex) {
- LOGGER.error(" ERROR - Could not run AAIConfig.init(). " + LogFormatTools.getStackTop(ex));
+ LOGGER.error(" ERROR - Could not run AAIConfig.init(). {}", LogFormatTools.getStackTop(ex));
System.exit(1);
}
// multiplicty definitions depends on which two types of nodes are being
// connected.
- Multimap<String, EdgeRule> edges = null;
- Set<String> labels = new HashSet<>();
-
- EdgeIngestor edgeIngestor = SpringContextAware.getBean(EdgeIngestor.class);
-
- try {
- edges = edgeIngestor.getAllCurrentRules();
- } catch (EdgeRuleNotFoundException e) {
- LOGGER.error("Unable to find all rules {}", LogFormatTools.getStackTop(e));
- }
-
- for (EdgeRule rule : edges.values()) {
- labels.add(rule.getLabel());
- }
+ makeEdgeLabels(graphMgmt);
- for (String label : labels) {
- if (graphMgmt.containsRelationType(label)) {
- String dmsg = " EdgeLabel [" + label + "] already existed. ";
- LOGGER.debug(dmsg);
- } else {
- String dmsg = "Making EdgeLabel: [" + label + "]";
- LOGGER.debug(dmsg);
- graphMgmt.makeEdgeLabel(label).multiplicity(Multiplicity.valueOf("MULTI")).make();
- }
- }
- Loader loader = LoaderUtil.getLatestVersion();
-
- Map<String, Introspector> objs = loader.getAllObjects();
+ Map<String, Introspector> objs = LoaderUtil.getLatestVersion().getAllObjects();
Map<String, PropertyKey> seenProps = new HashMap<>();
for (Introspector obj : objs.values()) {
dbPropName = alias.get();
}
if (graphMgmt.containsRelationType(dbPropName)) {
- String dmsg = " PropertyKey [" + dbPropName + "] already existed in the DB. ";
- LOGGER.debug(dmsg);
+ LOGGER.debug(" PropertyKey [{}] already existed in the DB. ", dbPropName);
} else {
Class<?> type = obj.getClass(propName);
Cardinality cardinality = Cardinality.SINGLE;
if (process) {
- String imsg = "Creating PropertyKey: [" + dbPropName + "], [" + type.getSimpleName() + "], ["
- + cardinality + "]";
- LOGGER.info(imsg);
+ LOGGER.info("Creating PropertyKey: [{}], [{}], [{}]",
+ dbPropName, type.getSimpleName(), cardinality);
PropertyKey propK;
if (!seenProps.containsKey(dbPropName)) {
propK = graphMgmt.makePropertyKey(dbPropName).dataType(type).cardinality(cardinality)
propK = seenProps.get(dbPropName);
}
if (graphMgmt.containsGraphIndex(dbPropName)) {
- String dmsg = " Index [" + dbPropName + "] already existed in the DB. ";
- LOGGER.debug(dmsg);
+ LOGGER.debug(" Index [{}] already existed in the DB. ", dbPropName);
} else {
if (obj.getIndexedProperties().contains(propName)) {
if (obj.getUniqueProperties().contains(propName)) {
- imsg = "Add Unique index for PropertyKey: [" + dbPropName + "]";
- LOGGER.info(imsg);
+ LOGGER.info("Add Unique index for PropertyKey: [{}]", dbPropName);
graphMgmt.buildIndex(dbPropName, Vertex.class).addKey(propK).unique()
.buildCompositeIndex();
} else {
- imsg = "Add index for PropertyKey: [" + dbPropName + "]";
- LOGGER.info(imsg);
+ LOGGER.info("Add index for PropertyKey: [{}]", dbPropName);
graphMgmt.buildIndex(dbPropName, Vertex.class).addKey(propK).buildCompositeIndex();
}
} else {
- imsg = "No index added for PropertyKey: [" + dbPropName + "]";
- LOGGER.info(imsg);
+ LOGGER.info("No index added for PropertyKey: [{}]", dbPropName);
}
}
}
}
}
- String imsg = "-- About to call graphMgmt commit";
- LOGGER.info(imsg);
+ LOGGER.info("-- About to call graphMgmt commit");
if (backend != null) {
- LOGGER.info(String.format("Successfully loaded the schema to %s", backend));
+ LOGGER.info("Successfully loaded the schema to {}", backend);
}
graphMgmt.commit();
}
+ private static void makeEdgeLabels(JanusGraphManagement graphMgmt) {
+ try {
+ EdgeIngestor edgeIngestor = SpringContextAware.getBean(EdgeIngestor.class);
+
+ Set<String> labels = Optional.ofNullable(edgeIngestor.getAllCurrentRules())
+ .map(collectValues(EdgeRule::getLabel))
+ .orElseGet(HashSet::new);
+
+ labels.forEach(label -> {
+ if (graphMgmt.containsRelationType(label)) {
+ LOGGER.debug(" EdgeLabel [{}] already existed. ", label);
+ } else {
+ LOGGER.debug("Making EdgeLabel: [{}]", label);
+ graphMgmt.makeEdgeLabel(label).multiplicity(Multiplicity.valueOf("MULTI")).make();
+ }
+ });
+ } catch (EdgeRuleNotFoundException e) {
+ LOGGER.error("Unable to find all rules {}", LogFormatTools.getStackTop(e));
+ }
+ }
+
+ /**
+ * Returns a function collecting all the values in a {@link com.google.common.collect.Multimap}
+ * given a mapping function
+ *
+ * @param f The mapper function
+ * @param <K> The type of key used by the provided {@link com.google.common.collect.Multimap}
+ * @param <V> The type of value used by the provided {@link com.google.common.collect.Multimap}
+ * @param <V0> The type which <V> is mapped to
+ */
+ private static <K, V, V0> Function<Multimap<K, V>, Set<V0>> collectValues(Function<V, V0> f) {
+ return as -> as.values().stream().map(f).collect(Collectors.toSet());
+ }
+
}
package org.onap.aai.dbgen;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.google.common.collect.Multimap;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.janusgraph.core.Cardinality;
-import org.janusgraph.core.JanusGraph;
import org.janusgraph.core.Multiplicity;
import org.janusgraph.core.PropertyKey;
import org.janusgraph.core.schema.JanusGraphManagement;
import org.onap.aai.logging.LogFormatTools;
import org.onap.aai.schema.enums.PropertyMetadata;
import org.onap.aai.util.AAIConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import java.util.*;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
import static org.onap.aai.db.props.AAIProperties.*;
private static final Logger LOGGER = LoggerFactory.getLogger(SchemaGenerator4Hist.class);
+ private SchemaGenerator4Hist(){
+
+ }
/**
* Load schema into JanusGraph.
*
- * @param graph
- * the graph
* @param graphMgmt
* the graph mgmt
*/
- public static void loadSchemaIntoJanusGraph(final JanusGraph graph, final JanusGraphManagement graphMgmt,
- String backend) {
+ public static void loadSchemaIntoJanusGraph(final JanusGraphManagement graphMgmt, String backend) {
try {
AAIConfig.init();
} catch (Exception ex) {
- LOGGER.error(" ERROR - Could not run AAIConfig.init(). " + LogFormatTools.getStackTop(ex));
- // System.out.println(" ERROR - Could not run AAIConfig.init(). ");
+ LOGGER.error(" ERROR - Could not run AAIConfig.init(). {}", LogFormatTools.getStackTop(ex));
System.exit(1);
}
for (String label : labels) {
if (graphMgmt.containsRelationType(label)) {
- String dmsg = " EdgeLabel [" + label + "] already existed. ";
- LOGGER.debug(dmsg);
+ LOGGER.debug(" EdgeLabel [{}] already existed. ", label);
} else {
- String dmsg = "Making EdgeLabel: [" + label + "]";
- LOGGER.debug(dmsg);
+ LOGGER.debug("Making EdgeLabel: [{}]", label);
graphMgmt.makeEdgeLabel(label).multiplicity(Multiplicity.valueOf("MULTI")).make();
}
}
dbPropName = alias.get();
}
if (graphMgmt.containsRelationType(dbPropName)) {
- String dmsg = " PropertyKey [" + dbPropName + "] already existed in the DB. ";
- LOGGER.debug(dmsg);
+ LOGGER.debug(" PropertyKey [{}] already existed in the DB. ", dbPropName);
} else {
Class<?> type = obj.getClass(propName);
Cardinality cardinality = Cardinality.LIST;
// above) will be stored in our db as a single String. And that
// single string will have Cardinality = LIST so we can track its
// history.
- //cardinality = Cardinality.SET;
type = obj.getGenericTypeClass(propName);
process = true;
} else if (obj.isSimpleType(propName)) {
if (process) {
- String imsg = " Creating PropertyKey: [" + dbPropName + "], [" + type.getSimpleName() + "], ["
- + cardinality + "]";
- LOGGER.info(imsg);
+ LOGGER.info(" Creating PropertyKey: [{}], [{}], [{}]",
+ dbPropName, type.getSimpleName(), cardinality);
PropertyKey propK;
if (!seenProps.containsKey(dbPropName)) {
propK = graphMgmt.makePropertyKey(dbPropName).dataType(type).cardinality(cardinality)
propK = seenProps.get(dbPropName);
}
if (graphMgmt.containsGraphIndex(dbPropName)) {
- String dmsg = " Index [" + dbPropName + "] already existed in the DB. ";
- LOGGER.debug(dmsg);
+ LOGGER.debug(" Index [{}] already existed in the DB. ", dbPropName);
} else {
if (obj.getIndexedProperties().contains(propName)) {
// NOTE - for History we never add a unique index - just a regular index
- imsg = "Add index for PropertyKey: [" + dbPropName + "]";
- LOGGER.info(imsg);
+ LOGGER.info("Add index for PropertyKey: [{}]", dbPropName);
graphMgmt.buildIndex(dbPropName, Vertex.class).addKey(propK).buildCompositeIndex();
} else {
- imsg = "No index needed/added for PropertyKey: [" + dbPropName + "]";
- LOGGER.info(imsg);
+ LOGGER.info("No index needed/added for PropertyKey: [{}]", dbPropName);
}
}
}
// only have one of them. That is, a Property can show up many times in a
// node, but each instance of that property will only have a single start-ts,
// end-ts, end-source-of-truth. Same goes for a node or edge itself.
- if (graphMgmt.containsRelationType(END_SOT)) {
- String dmsg = "PropertyKey [" + END_SOT + "] already existed in the DB. ";
- LOGGER.debug(dmsg);
- } else if (!seenProps.containsKey(END_SOT) ) {
- String imsg = " Creating PropertyKey: [" + END_SOT + "], [String], [SINGLE]";
- LOGGER.info(imsg);
- graphMgmt.makePropertyKey(END_SOT).dataType(String.class)
- .cardinality(Cardinality.SINGLE).make();
- }
-
- if (graphMgmt.containsRelationType(START_TS)) {
- String dmsg = " PropertyKey [" + START_TS + "] already existed in the DB. ";
- LOGGER.debug(dmsg);
- } else if (!seenProps.containsKey(START_TS) ) {
- String imsg = " Creating PropertyKey: [" + START_TS + "], [Long], [SINGLE]";
- LOGGER.info(imsg);
- graphMgmt.makePropertyKey(START_TS).dataType(Long.class)
- .cardinality(Cardinality.SINGLE).make();
- }
-
- if (graphMgmt.containsRelationType(END_TS)) {
- String dmsg = "PropertyKey [" + END_TS + "] already existed in the DB. ";
- LOGGER.debug(dmsg);
- } else if (!seenProps.containsKey(END_TS) ) {
- String imsg = " Creating PropertyKey: [" + END_TS + "], [Long], [SINGLE]";
- LOGGER.info(imsg);
- graphMgmt.makePropertyKey(END_TS).dataType(Long.class)
- .cardinality(Cardinality.SINGLE).make();
- }
-
- if (graphMgmt.containsRelationType(START_TX_ID)) {
- String dmsg = "PropertyKey [" + START_TX_ID + "] already existed in the DB. ";
- LOGGER.debug(dmsg);
- } else if (!seenProps.containsKey(START_TX_ID) ) {
- String imsg = " Creating PropertyKey: [" + START_TX_ID + "], [String], [SINGLE]";
- LOGGER.info(imsg);
- graphMgmt.makePropertyKey(START_TX_ID).dataType(String.class)
- .cardinality(Cardinality.SINGLE).make();
- }
+ makeNewProperty(graphMgmt, seenProps, String.class, END_SOT);
+ makeNewProperty(graphMgmt, seenProps, Long.class, START_TS);
+ makeNewProperty(graphMgmt, seenProps, Long.class, END_TS);
+ makeNewProperty(graphMgmt, seenProps, String.class, START_TX_ID);
+ makeNewProperty(graphMgmt, seenProps, String.class, END_TX_ID);
- if (graphMgmt.containsRelationType(END_TX_ID)) {
- String dmsg = "PropertyKey [" + END_TX_ID + "] already existed in the DB. ";
- LOGGER.debug(dmsg);
- } else if (!seenProps.containsKey(END_TX_ID) ) {
- String imsg = " Creating PropertyKey: [" + END_TX_ID + "], [String], [SINGLE]";
- LOGGER.info(imsg);
- graphMgmt.makePropertyKey(END_TX_ID).dataType(String.class)
- .cardinality(Cardinality.SINGLE).make();
- }
String imsg = "-- About to call graphMgmt commit";
LOGGER.info(imsg);
graphMgmt.commit();
if (backend != null) {
- LOGGER.info("Successfully loaded the schema to " + backend);
+ LOGGER.info("Successfully loaded the schema to {}", backend);
}
}
+ private static <T> void makeNewProperty(JanusGraphManagement graphMgmt,
+ Map<String, PropertyKey> seenProps,
+ Class<T> type,
+ String propertyName) {
+ if (graphMgmt.containsRelationType(propertyName)) {
+ LOGGER.debug("PropertyKey [{}] already existed in the DB.", propertyName);
+ } else if (!seenProps.containsKey(propertyName)) {
+ LOGGER.info("Creating PropertyKey: [{}], [{}], [{}]",
+ propertyName, type.getSimpleName(), Cardinality.SINGLE);
+ graphMgmt.makePropertyKey(propertyName).dataType(type).cardinality(Cardinality.SINGLE)
+ .make();
+ }
+ }
}
logger.info("-- loading schema into JanusGraph");
if ("true".equals(SpringContextAware.getApplicationContext().getEnvironment().getProperty("history.enabled", "false"))) {
- SchemaGenerator4Hist.loadSchemaIntoJanusGraph(graph, graphMgt, IN_MEMORY);
+ SchemaGenerator4Hist.loadSchemaIntoJanusGraph(graphMgt, IN_MEMORY);
} else {
SchemaGenerator.loadSchemaIntoJanusGraph(graphMgt, IN_MEMORY);
}
private static final long serialVersionUID = -5615651557821878103L;
+ private static final String AAI_MSG="AAI_3000";
public AAIUnmarshallingException() {
}
public AAIUnmarshallingException(String message) {
- super("AAI_3000", message);
+ super(AAI_MSG, message);
}
public AAIUnmarshallingException(Throwable cause) {
- super("AAI_3000", cause);
+ super(AAI_MSG, cause);
}
public AAIUnmarshallingException(String message, Throwable cause) {
- super("AAI_3000", cause, message);
+ super(AAI_MSG, cause, message);
}
}
static final String REQUEST_TIMEOUT_STRING =
"Request to validation service took longer than the currently set timeout";
- static final String VALIDATION_ENDPOINT = "/v1/app/validate";
- static final String VALIDATION_HEALTH_ENDPOINT = "/v1/core/core-service/info";
+ static final String VALIDATION_ENDPOINT = "/v1/validate";
+ static final String VALIDATION_HEALTH_ENDPOINT = "/v1/info";
private static final String ENTITY_TYPE = "entity-type";
private static final String ACTION = "action";
private static final String ARGUMENT2 = "#!#argument#!#";
private static final String HAS = ".has('";
private static final String SINGLE_QUOTE = "'";
- private static final String ESCAPE_SINGLE_QUOTE = "\\'";
+ private static final String ESCAPE_SINGLE_QUOTE = "\\\'";
private GremlinGroovyShell gremlinGroovy = new GremlinGroovyShell();
private GraphTraversal<?, ?> completeTraversal = null;
protected List<String> list = null;
String term = "";
if (value != null && !(value instanceof String)) {
String valueString = value.toString();
+
if (valueString.indexOf('\'') != -1) {
value = valueString.replace(SINGLE_QUOTE, ESCAPE_SINGLE_QUOTE);
}
LOGGER.trace("Inside getVerticesByProperty(): key = {}, value = {}", key, value);
term = value.toString();
+ } else if (value != null && value instanceof String) {
+ String valueString = value.toString();
+
+ if (valueString.indexOf('\'') != -1) {
+ value = valueString.replace(SINGLE_QUOTE, ESCAPE_SINGLE_QUOTE);
+ }
+ LOGGER.trace("Inside getVerticesByProperty(): key = {}, value = {}", key, value);
+ term = "'" + value + "'";
} else {
term = "'" + value + "'";
}
-/**
+/*
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
import java.util.concurrent.ThreadPoolExecutor;
public class RestHandlerService {
- private static RestHandlerService single_instance = null;
+ private static RestHandlerService singleInstance = null;
public ThreadPoolExecutor executor;
- // private constructor restricted to this class itself
private RestHandlerService() {
executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(50);
}
* @return single instance of RestHandlerService
*/
public static RestHandlerService getInstance() {
- if (single_instance == null) {
- single_instance = new RestHandlerService();
+ if (singleInstance == null) {
+ singleInstance = new RestHandlerService();
}
- return single_instance;
+ return singleInstance;
}
}
@Value("${delta.events.enabled:false}")
private boolean isDeltaEventsEnabled;
+ private String serverBase;
+
@Autowired
private XmlFormatTransformer xmlFormatTransformer;
return this;
}
+ public HttpEntry setHttpEntryProperties(SchemaVersion version, String serverBase) {
+ this.version = version;
+ this.loader = loaderFactory.createLoaderForVersion(introspectorFactoryType, version);
+ this.dbEngine = new JanusGraphDBEngine(queryStyle, loader);
+
+ getDbEngine().startTransaction();
+ this.notification = new UEBNotification(loader, loaderFactory, schemaVersions);
+ if("true".equals(AAIConfig.get("aai.notification.depth.all.enabled", "true"))){
+ this.notificationDepth = AAIProperties.MAXIMUM_DEPTH;
+ } else {
+ this.notificationDepth = AAIProperties.MINIMUM_DEPTH;
+ }
+
+ this.serverBase = serverBase;
+ return this;
+ }
+
public HttpEntry setHttpEntryProperties(SchemaVersion version, UEBNotification notification) {
this.version = version;
this.loader = loaderFactory.createLoaderForVersion(introspectorFactoryType, version);
public Pair<Boolean, List<Pair<URI, Response>>> process(List<DBRequest> requests, String sourceOfTruth,
boolean enableResourceVersion) throws AAIException {
- DBSerializer serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth, notificationDepth);
+ DBSerializer serializer = null;
+
+ if(serverBase != null){
+ serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth, notificationDepth, serverBase);
+ } else {
+ serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth, notificationDepth);
+ }
+
Response response;
Introspector obj;
QueryParser query;
}
} else {
FormatFactory ff =
- new FormatFactory(loader, serializer, schemaVersions, basePath + "/");
+ new FormatFactory(loader, serializer, schemaVersions, basePath + "/", serverBase);
Formatter formatter = ff.get(format, params);
result = formatter.output(vertices.stream().map(vertex -> (Object) vertex)
.collect(Collectors.toList())).toString();
}
} else {
FormatFactory ff =
- new FormatFactory(loader, serializer, schemaVersions, basePath + "/");
+ new FormatFactory(loader, serializer, schemaVersions, basePath + "/", serverBase);
Formatter formatter = ff.get(format, params);
result = formatter.output(vertices.stream().map(vertex -> (Object) vertex)
.collect(Collectors.toList())).toString();
initBeans();
}
+ public DBSerializer(SchemaVersion version,
+ TransactionalGraphEngine engine,
+ ModelType introspectionType,
+ String sourceOfTruth,
+ int notificationDepth,
+ String serverBase) throws AAIException {
+ this.engine = engine;
+ this.sourceOfTruth = sourceOfTruth;
+ this.introspectionType = introspectionType;
+ this.schemaVersions = (SchemaVersions) SpringContextAware.getBean("schemaVersions");
+ SchemaVersion latestVersion = schemaVersions.getDefaultVersion();
+ this.latestLoader =
+ SpringContextAware.getBean(LoaderFactory.class).createLoaderForVersion(introspectionType, latestVersion);
+ this.version = version;
+ this.loader =
+ SpringContextAware.getBean(LoaderFactory.class).createLoaderForVersion(introspectionType, version);
+ this.namedPropNodes = this.latestLoader.getNamedPropNodes();
+ this.baseURL = serverBase;
+ this.currentTimeMillis = System.currentTimeMillis();
+ this.notificationDepth = notificationDepth;
+ initBeans();
+ }
+
private void initBeans() {
// TODO proper spring wiring, but that requires a lot of refactoring so for now we have this
ApplicationContext ctx = SpringContextAware.getApplicationContext();
Set<Vertex> seen = new HashSet<>();
int depth = 0;
StopWatch.conditionalStart();
- this.dbToObject(obj, v, seen, depth, false, FALSE);
+ this.dbToObject(obj, v, seen, depth, true, FALSE);
dbTimeMsecs += StopWatch.stopIfStarted();
return obj;
// only for the older apis and the new apis if the edge rule
// is removed will not be seen in the newer version of the API
- String bNodeType = null;
+ String bNodeType;
if (otherV.property(AAIProperties.NODE_TYPE).isPresent()) {
- bNodeType = otherV.property(AAIProperties.NODE_TYPE).value().toString();
+ bNodeType = otherV.value(AAIProperties.NODE_TYPE);
} else {
continue;
}
-/**
+/*
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
public abstract class QueryEngine {
- final protected GraphTraversalSource g;
+ protected final GraphTraversalSource g;
protected double dbTimeMsecs = 0;
/**
public abstract List<Path> findCousinsAsPath(Vertex start);
public abstract double getDBTimeMsecs();
-
}
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.VertexProperty;
import org.onap.aai.db.props.AAIProperties;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.Introspector;
import org.onap.aai.introspection.Loader;
+import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
import org.onap.aai.logging.LogFormatTools;
import org.onap.aai.serialization.db.DBSerializer;
import org.onap.aai.serialization.queryformats.exceptions.AAIFormatQueryResultFormatNotSupported;
import org.onap.aai.serialization.queryformats.params.NodesOnly;
import org.onap.aai.serialization.queryformats.utils.UrlBuilder;
+import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
}
public Optional<JsonObject> createPropertiesObject(Vertex v) throws AAIFormatVertexException {
- JsonObject json = new JsonObject();
- Iterator<VertexProperty<Object>> iter = v.properties();
+ try {
+ final Introspector obj =
+ loader.introspectorFromName(v.<String>property(AAIProperties.NODE_TYPE).orElse(null));
- while (iter.hasNext()) {
- VertexProperty<Object> prop = iter.next();
- if (prop.value() instanceof String) {
- json.addProperty(prop.key(), (String) prop.value());
- } else if (prop.value() instanceof Boolean) {
- json.addProperty(prop.key(), (Boolean) prop.value());
- } else if (prop.value() instanceof Number) {
- json.addProperty(prop.key(), (Number) prop.value());
- } else if (prop.value() instanceof List) {
- Gson gson = new Gson();
- String list = gson.toJson(prop.value());
-
- json.addProperty(prop.key(), list);
- } else {
- // throw exception?
- return null;
+ final List<Vertex> wrapper = new ArrayList<>();
+ wrapper.add(v);
+
+ try {
+ serializer.dbToObject(wrapper, obj, 0, true, "false");
+ } catch (AAIException | UnsupportedEncodingException e) {
+ throw new AAIFormatVertexException(
+ "Failed to format vertex - error while serializing: " + e.getMessage(), e);
}
- }
- return Optional.of(json);
+ final String json = obj.marshal(false);
+ return Optional.of(parser.parse(json).getAsJsonObject());
+ } catch (AAIUnknownObjectException e) {
+ return Optional.empty();
+ }
}
public Optional<JsonObject> createSelectedPropertiesObject(Vertex v, Map<String, List<String>> selectedProps) throws AAIFormatVertexException {
json.addProperty(prop.key(), gson.toJson(prop.value()));
} else {
// throw exception?
- return null;
+ return Optional.empty();
}
}
} else {
json.add(inner);
} else {
Optional<JsonObject> obj = this.getJsonFromVertex((Vertex)l, properties);
- json.add(obj.get());
+ if(obj.isPresent()) json.add(obj.get());
}
}
return Optional.of(json);
import org.onap.aai.exceptions.AAIException;
public enum Format {
- graphson, pathed, pathed_resourceversion, id, resource, simple, resource_and_url, console, raw, count, resource_with_sot, state, lifecycle, changes, aggregate;
+ graphson, pathed, pathed_resourceversion, id, resource, simple, resource_and_url, console, raw, count, resource_with_sot, state, lifecycle, changes, aggregate, tree;
public static Format getFormat(String format) throws AAIException {
try {
this.injector = QueryParamInjector.getInstance();
}
+ public FormatFactory(Loader loader, DBSerializer serializer, SchemaVersions schemaVersions, String basePath, String serverBase)
+ throws AAIException {
+ this.loader = loader;
+ this.serializer = serializer;
+ this.urlBuilder = new UrlBuilder(loader.getVersion(), serializer, serverBase, schemaVersions, basePath);
+ this.injector = QueryParamInjector.getInstance();
+ }
+
public Formatter get(Format format) throws AAIException {
return get(format, new MultivaluedHashMap<>());
}
formatter =
new Formatter(inject(new LifecycleFormat.Builder(loader, serializer, urlBuilder), params).build(format));
break;
+ case tree:
+ formatter = new Formatter(
+ inject(new TreeFormat.Builder(loader, serializer, urlBuilder), params).build());
+ break;
default:
break;
package org.onap.aai.serialization.queryformats;
import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
+import java.util.stream.Collectors;
+import org.apache.commons.lang3.tuple.ImmutableTriple;
+import org.apache.commons.lang3.tuple.Pair;
import org.apache.tinkerpop.gremlin.process.traversal.Path;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.onap.aai.serialization.queryformats.exceptions.AAIFormatQueryResultFormatNotSupported;
import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
+import java.util.*;
public abstract class MultiFormatMapper implements FormatMapper {
+ Logger logger = LoggerFactory.getLogger(MultiFormatMapper.class);
+
protected boolean isTree = false;
+ protected static final String PROPERTIES_KEY = "properties";
+ protected static final String NODE_TYPE_KEY = "node-type";
+
+ protected static final String RETURNED_EMPTY_JSONARRAY_MSG =
+ "Returned empty JsonArray - Could not populate nested json objects for wrapper: {}";
@Override
public Optional<JsonObject> formatObject(Object input)
- throws AAIFormatVertexException, AAIFormatQueryResultFormatNotSupported {
+ throws AAIFormatVertexException, AAIFormatQueryResultFormatNotSupported {
if (input instanceof Vertex) {
+ logger.debug("Formatting vertex object");
return this.getJsonFromVertex((Vertex) input);
} else if (input instanceof Tree) {
+ logger.debug("Formatting tree object");
if (isTree) {
- return this.getRelatedNodesFromTree((Tree<?>) input);
+ return this.getRelatedNodesFromTree((Tree<?>) input, null);
} else {
- return this.getJsonFomTree((Tree<?>) input);
+ return this.getJsonFromTree((Tree<?>) input);
}
} else if (input instanceof Path) {
+ logger.debug("Formatting path object");
return this.getJsonFromPath((Path) input);
} else {
throw new AAIFormatQueryResultFormatNotSupported();
public Optional<JsonObject> formatObject(Object input, Map<String, List<String>> properties)
throws AAIFormatVertexException, AAIFormatQueryResultFormatNotSupported {
if (input instanceof Vertex) {
+ logger.debug("Formatting vertex object with properties map filter");
return this.getJsonFromVertex((Vertex) input, properties);
} else if (input instanceof Tree) {
+ logger.debug("Formatting tree object with properties map filter");
if (isTree) {
- return this.getRelatedNodesFromTree((Tree<?>) input);
+ return this.getRelatedNodesFromTree((Tree<?>) input, properties);
} else {
- return this.getJsonFomTree((Tree<?>) input);
+ return this.getJsonFromTree((Tree<?>) input);
}
} else if (input instanceof Path) {
+ logger.debug("Formatting path object");
return this.getJsonFromPath((Path) input);
} else {
throw new AAIFormatQueryResultFormatNotSupported();
return Optional.of(jo);
}
- protected Optional<JsonObject> getJsonFomTree(Tree<?> tree) throws AAIFormatVertexException {
-
+ /**
+ * Returns an Optional<JsonObject> object using "nodes" as a wrapper to encapsulate json objects
+ * @param tree
+ * @return
+ * @throws AAIFormatVertexException
+ */
+ protected Optional<JsonObject> getJsonFromTree(Tree<?> tree) throws AAIFormatVertexException {
if (tree.isEmpty()) {
return Optional.of(new JsonObject());
}
+ String nodeIdentifier = "nodes";
JsonObject t = new JsonObject();
- JsonArray ja = this.getNodesArray(tree, "nodes");
+ JsonArray ja = this.getNodesArray(tree, null, nodeIdentifier);
if (ja.size() > 0) {
t.add("nodes", ja);
+ } else {
+ logger.debug(RETURNED_EMPTY_JSONARRAY_MSG, nodeIdentifier);
}
return Optional.of(t);
}
- protected Optional<JsonObject> getRelatedNodesFromTree(Tree<?> tree) throws AAIFormatVertexException {
+ /**
+ * Returns an Optional<JsonObject> object using "related-nodes" to encapsulate nested json objects.
+ * Primarily intended to be utilized by the "as-tree" query parameter feature
+ * @param tree
+ * @param properties
+ * @return
+ * @throws AAIFormatVertexException
+ */
+ protected Optional<JsonObject> getRelatedNodesFromTree(Tree<?> tree, Map<String, List<String>> properties) throws AAIFormatVertexException {
if (tree.isEmpty()) {
return Optional.of(new JsonObject());
}
+ String nodeIdentifier = "related-nodes";
+
+ // Creating another DS to help with calls in O(1)
+ Map<String, Set<String>> filterPropertiesMap = createFilteredPropertyMap(properties);
JsonObject t = new JsonObject();
- JsonArray ja = this.getNodesArray(tree, "related-nodes");
+ JsonArray ja = this.getNodesArray(tree, filterPropertiesMap, nodeIdentifier);
if (ja.size() > 0) {
t.add("results", ja);
return Optional.of(t);
+ } else {
+ logger.debug(RETURNED_EMPTY_JSONARRAY_MSG, nodeIdentifier);
}
return Optional.empty();
}
- protected JsonArray getNodesArray(Tree<?> tree, String nodeIdentifier) throws AAIFormatVertexException {
-
+ /**
+ * Returns JsonArray Object populated with nested json wrapped by the nodeIdentifier parameter
+ * @param tree
+ * @param filterPropertiesMap
+ * @param nodeIdentifier
+ * @return
+ * @throws AAIFormatVertexException
+ */
+ protected JsonArray getNodesArray(Tree<?> tree, Map<String, Set<String>> filterPropertiesMap, String nodeIdentifier) throws AAIFormatVertexException {
JsonArray nodes = new JsonArray();
for (Map.Entry<?, ? extends Tree<?>> entry : tree.entrySet()) {
JsonObject me = new JsonObject();
if (entry.getKey() instanceof Vertex) {
Optional<JsonObject> obj = this.getJsonFromVertex((Vertex) entry.getKey());
if (obj.isPresent()) {
- me = obj.get();
+ me = getPropertyFilteredObject(obj, filterPropertiesMap);
} else {
continue;
}
}
- JsonArray ja = this.getNodesArray(entry.getValue(), nodeIdentifier);
+ JsonArray ja = this.getNodesArray(entry.getValue(), filterPropertiesMap, nodeIdentifier);
if (ja.size() > 0) {
me.add(nodeIdentifier, ja);
+ } else {
+ logger.debug(RETURNED_EMPTY_JSONARRAY_MSG, nodeIdentifier);
}
nodes.add(me);
}
return nodes;
}
+ /**
+ * Returns a Map<String, Set<String>> object through converting given map parameter
+ * @param properties
+ * @return
+ */
+ protected Map<String, Set<String>> createFilteredPropertyMap(Map<String, List<String>> properties) {
+ if (properties == null)
+ return new HashMap<>();
+
+ return properties.entrySet().stream()
+ .map(entry -> {
+ Set<String> newSet = entry.getValue().stream()
+ .map(this::truncateApostrophes)
+ .collect(Collectors.toSet());
+
+ return Pair.of(entry.getKey(), newSet);
+ }
+ ).collect(Collectors.toMap(Pair::getKey, Pair::getValue));
+ }
+
+ /**
+ * Returns a string with it's apostrophes truncated at the start and end.
+ * @param s
+ * @return
+ */
+ protected String truncateApostrophes(String s) {
+ if (s == null || s.isEmpty()) {
+ return s;
+ }
+ if (s.startsWith("'") && s.endsWith("'")) {
+ s = s.substring(1, s.length() - 1);
+ }
+ return s;
+ }
+
+ /**
+ * Filters the given Optional<JsonObject> with the properties under a properties field
+ * or the properties under its respective node type.
+ * @param obj
+ * @param filterPropertiesMap
+ * @return
+ */
+ protected JsonObject getPropertyFilteredObject(Optional<JsonObject> obj,
+ Map<String, Set<String>> filterPropertiesMap) {
+ return obj.map(
+ jsonObj -> {
+ if (filterPropertiesMap == null || filterPropertiesMap.isEmpty()) {
+ return jsonObj;
+ } else {
+ ImmutableTriple<JsonObject, Optional<String>, Optional<JsonObject>> triple =
+ cloneObjectAndExtractNodeTypeAndProperties(jsonObj);
+
+ JsonObject result = triple.left;
+ Optional<String> nodeType = triple.middle;
+ Optional<JsonObject> properties = triple.right;
+
+ // Filter current object based on it containing fields: "node-type" and "properties"
+ if (nodeType.isPresent() && properties.isPresent()) {
+ filterByNodeTypeAndProperties(result, nodeType.get(), properties.get(), filterPropertiesMap);
+ } else {
+ // filter current object based on the: key - nodeType & value - JsonObject of nodes properties
+ filterByJsonObj(result, jsonObj, filterPropertiesMap);
+ }
+
+ return result;
+ }
+ }
+ ).orElseGet(JsonObject::new);
+ }
+
+ private ImmutableTriple<JsonObject, Optional<String>, Optional<JsonObject>> cloneObjectAndExtractNodeTypeAndProperties(
+ JsonObject jsonObj) {
+ JsonObject result = new JsonObject();
+ Optional<String> nodeType = Optional.empty();
+ Optional<JsonObject> properties = Optional.empty();
+
+ // clone object
+ for (Map.Entry<String, JsonElement> mapEntry : jsonObj.entrySet()) {
+ String key = mapEntry.getKey();
+ JsonElement value = mapEntry.getValue();
+
+ // also, check if payload has node-type and properties fields
+ if (key.equals(NODE_TYPE_KEY) && value != null) {
+ nodeType = Optional.of(value.getAsString());
+ } else if (key.equals(PROPERTIES_KEY) && value != null && value.isJsonObject()) {
+ properties = Optional.of(value.getAsJsonObject());
+ }
+ result.add(key, value);
+ }
+
+ return ImmutableTriple.of(result, nodeType, properties);
+ }
+
+ /**
+ * Returns a JsonObject with filtered properties using "node-type" and "properties"
+ * Used for formats with payloads similar to simple and raw
+ * @param result
+ * @param nodeType
+ * @param properties
+ * @param filterPropertiesMap
+ * @return
+ */
+ private JsonObject filterByNodeTypeAndProperties(JsonObject result, String nodeType, JsonObject properties, Map<String, Set<String>> filterPropertiesMap) {
+ if (result == null || nodeType == null || nodeType.isEmpty() || properties == null || filterPropertiesMap == null) {
+ return result;
+ }
+ if (filterPropertiesMap.containsKey(nodeType)) { // filterPropertiesMap keys are nodeTypes - keys are obtained from the incoming query request
+ Set<String> filterSet = filterPropertiesMap.get(nodeType);
+ JsonObject filteredProperties = new JsonObject();
+ for (String property : filterSet) { // Each nodeType should have a set of properties to be retained in the response
+ if (properties.get(property) != null) {
+ filteredProperties.add(property, properties.get(property));
+ }
+ }
+ result.remove(PROPERTIES_KEY);
+ result.add(PROPERTIES_KEY, filteredProperties);
+ }
+ return result;
+ }
+
+ /**
+ * Returns a JsonObject with its properties filtered
+ * @param result
+ * @param jsonObj
+ * @param filterPropertiesMap
+ * @return
+ */
+ private JsonObject filterByJsonObj(JsonObject result, JsonObject jsonObj, Map<String, Set<String>> filterPropertiesMap) {
+ if (result == null || jsonObj == null || filterPropertiesMap == null) {
+ return result;
+ }
+
+ for (Map.Entry<String, JsonElement> mapEntry : jsonObj.entrySet()) {
+ String key = mapEntry.getKey();
+ JsonElement value = mapEntry.getValue();
+ JsonObject filteredProperties = new JsonObject();
+ if (value != null && value.isJsonObject() && filterPropertiesMap.containsKey(key)) {
+ JsonObject joProperties = value.getAsJsonObject();
+ Set<String> filterSet = filterPropertiesMap.get(key);
+ for (String property : filterSet) {
+ if (joProperties.get(property) != null) {
+ filteredProperties.add(property, joProperties.get(property));
+ }
+ }
+ result.remove(key);
+ result.add(key, filteredProperties);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns a filtered JsonObject with properties contained in the parameter filterPropertiesMap
+ * @param properties
+ * @param filterPropertiesMap
+ * @return
+ */
+ protected JsonObject filterProperties(Optional<JsonObject> properties, String nodeType,
+ Map<String, Set<String>> filterPropertiesMap) {
+ return properties.map(jo -> {
+ if (filterPropertiesMap == null || filterPropertiesMap.isEmpty()) {
+ return properties.get();
+ }
+
+ JsonObject result = new JsonObject();
+ // clone the object
+ for (Map.Entry<String, JsonElement> mapEntry : jo.entrySet()) {
+ String key = mapEntry.getKey();
+ JsonElement value = mapEntry.getValue();
+ result.add(key, value);
+ }
+
+ // filter the object
+ if (filterPropertiesMap.containsKey(nodeType)) {
+ Set<String> filterSet = filterPropertiesMap.get(nodeType);
+ for (Map.Entry<String, JsonElement> mapEntry : jo.entrySet()) {
+ String key = mapEntry.getKey();
+ if (!filterSet.contains(key)) {
+ result.remove(key);
+ }
+ }
+ }
+ return result;
+ }).orElseGet(JsonObject::new);
+ }
+
@Override
public int parallelThreshold() {
return 100;
this.parser = new JsonParser();
this.loader = builder.getLoader();
this.isTree = builder.isTree();
+ this.includeUrl = builder.isIncludeUrl();
}
@Override
return 20;
}
- public PathedURL includeUrl() {
- this.includeUrl = true;
- return this;
- }
-
@Override
protected Optional<JsonObject> getJsonFromVertex(Vertex v) throws AAIFormatVertexException {
import java.io.UnsupportedEncodingException;
import java.util.*;
-import java.util.stream.Stream;
-import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.onap.aai.db.props.AAIProperties;
}
@Override
- protected Optional<JsonObject> getRelatedNodesFromTree(Tree<?> tree) throws AAIFormatVertexException {
+ protected Optional<JsonObject> getRelatedNodesFromTree(Tree<?> tree, Map<String, List<String>> properties) throws AAIFormatVertexException {
if (tree.isEmpty()) {
return Optional.of(new JsonObject());
}
+
+ Map<String, Set<String>> filterPropertiesMap = createFilteredPropertyMap(properties);
+
JsonObject t = new JsonObject();
- JsonArray ja = this.getRelatedNodesArray(tree, "related-nodes");
+ JsonArray ja = this.getRelatedNodesArray(tree, filterPropertiesMap,"related-nodes");
if (ja.size() > 0) {
t.add("results", ja);
return Optional.of(t);
return Optional.empty();
}
- protected JsonArray getRelatedNodesArray(Tree<?> tree, String nodeIdentifier) throws AAIFormatVertexException {
+ protected JsonArray getRelatedNodesArray(Tree<?> tree, Map<String, Set<String>> filterPropertiesMap, String nodeIdentifier) throws AAIFormatVertexException {
JsonArray nodes = new JsonArray();
if (tree.isEmpty()) {
return nodes;
obj = this.getJsonFromVertex((Vertex) entry.getKey());
}
if (obj != null && obj.isPresent()) {
- me = obj.get();
+ me = getPropertyFilteredObject(obj, filterPropertiesMap);
} else {
continue;
}
}
- JsonArray ja = this.getRelatedNodesArray(entry.getValue(), nodeIdentifier);
+ JsonArray ja = this.getRelatedNodesArray(entry.getValue(), filterPropertiesMap, nodeIdentifier);
if (ja.size() > 0) {
try {
- me.entrySet().stream().findFirst().get().getValue().getAsJsonObject().add(nodeIdentifier, ja);
+ for (Map.Entry<String, JsonElement> mapEntry : me.entrySet()) {
+ JsonElement value = mapEntry.getValue();
+ if (value != null && value.isJsonObject()) {
+ value.getAsJsonObject().add(nodeIdentifier, ja);
+ }
+ }
} catch(Exception e) {
+ logger.debug("Failed to add related-nodes array: {}", e.getMessage());
throw new AAIFormatVertexException("Failed to add related-nodes array: " + e.getMessage(), e);
}
}
}
@Override
- protected Optional<JsonObject> getJsonFromVertex(Vertex input, Map<String, List<String>> properties) throws AAIFormatVertexException {
- return Optional.empty();
+ protected Optional<JsonObject> getJsonFromVertex(Vertex v, Map<String, List<String>> properties) throws AAIFormatVertexException {
+ JsonObject json = new JsonObject();
+
+ if (this.includeUrl) {
+ json.addProperty("url", this.urlBuilder.pathed(v));
+ }
+ Optional<JsonObject> jsonObject = this.vertexToJsonObject(v);
+ if (jsonObject.isPresent()) {
+ String nodeType = v.<String>value(AAIProperties.NODE_TYPE);
+ Map<String, Set<String>> filterPropertiesMap = createFilteredPropertyMap(properties); // this change is for resource_and_url with/out as-tree. and no as-tree req
+ JsonObject jo = filterProperties(jsonObject, nodeType, filterPropertiesMap);
+ json.add(v.<String>property(AAIProperties.NODE_TYPE).orElse(null), jo);
+ } else {
+ return Optional.empty();
+ }
+ return Optional.of(json);
}
protected Optional<JsonObject> vertexToJsonObject(Vertex v) throws AAIFormatVertexException {
}
try {
final Introspector obj =
- getLoader().introspectorFromName(v.<String>property(AAIProperties.NODE_TYPE).orElse(null));
+ getLoader().introspectorFromName(v.<String>property(AAIProperties.NODE_TYPE).orElse(null));
final List<Vertex> wrapper = new ArrayList<>();
getSerializer().dbToObject(wrapper, obj, this.depth, this.nodesOnly, "false", isSkipRelatedTo);
} catch (AAIException | UnsupportedEncodingException e) {
throw new AAIFormatVertexException(
- "Failed to format vertex - error while serializing: " + e.getMessage(), e);
+ "Failed to format vertex - error while serializing: " + e.getMessage(), e);
}
final String json = obj.marshal(false);
--- /dev/null
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-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.aai.serialization.queryformats;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.util.Map.Entry;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.onap.aai.db.props.AAIProperties;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.Introspector;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
+import org.onap.aai.logging.LogFormatTools;
+import org.onap.aai.serialization.db.DBSerializer;
+import org.onap.aai.serialization.queryformats.exceptions.AAIFormatQueryResultFormatNotSupported;
+import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
+import org.onap.aai.serialization.queryformats.params.Depth;
+import org.onap.aai.serialization.queryformats.params.NodesOnly;
+import org.onap.aai.serialization.queryformats.utils.UrlBuilder;
+
+import java.io.UnsupportedEncodingException;
+import java.util.*;
+
+public class TreeFormat extends MultiFormatMapper {
+ private static final EELFLogger TREE_FORMAT_LOGGER = EELFManager.getInstance().getLogger(TreeFormat.class);
+ protected JsonParser parser = new JsonParser();
+ protected final DBSerializer serializer;
+ protected final Loader loader;
+ protected final UrlBuilder urlBuilder;
+ protected final int depth;
+ protected final boolean nodesOnly;
+
+ protected TreeFormat(Builder builder) {
+ this.urlBuilder = builder.getUrlBuilder();
+ this.loader = builder.getLoader();
+ this.serializer = builder.getSerializer();
+ this.depth = builder.getDepth();
+ this.nodesOnly = builder.isNodesOnly();
+ }
+
+ @Override
+ public int parallelThreshold() {
+ return 100;
+ }
+
+ public static class Builder implements NodesOnly<Builder>, Depth<Builder> {
+
+ protected final Loader loader;
+ protected final DBSerializer serializer;
+ protected final UrlBuilder urlBuilder;
+ protected boolean includeUrl = false;
+ protected boolean nodesOnly = false;
+ protected int depth = 1;
+ protected boolean modelDriven = false;
+
+ public Builder(Loader loader, DBSerializer serializer, UrlBuilder urlBuilder) {
+ this.loader = loader;
+ this.serializer = serializer;
+ this.urlBuilder = urlBuilder;
+ }
+
+ protected Loader getLoader() {
+ return this.loader;
+ }
+
+ protected DBSerializer getSerializer() {
+ return this.serializer;
+ }
+
+ protected UrlBuilder getUrlBuilder() {
+ return this.urlBuilder;
+ }
+
+ public Builder includeUrl() {
+ this.includeUrl = true;
+ return this;
+ }
+
+ public Builder nodesOnly(Boolean nodesOnly) {
+ this.nodesOnly = nodesOnly;
+ return this;
+ }
+
+ public boolean isNodesOnly() {
+ return this.nodesOnly;
+ }
+
+ public Builder depth(Integer depth) {
+ this.depth = depth;
+ return this;
+ }
+
+ public int getDepth() {
+ return this.depth;
+ }
+
+ public boolean isIncludeUrl() {
+ return this.includeUrl;
+ }
+
+ public Builder modelDriven() {
+ this.modelDriven = true;
+ return this;
+ }
+
+ public boolean getModelDriven() {
+ return this.modelDriven;
+ }
+
+ public TreeFormat build() {
+ return new TreeFormat(this);
+ }
+ }
+
+ public JsonArray process(List<Object> queryResults, Map<String, List<String>> properties) {
+ JsonArray body = new JsonArray();
+ for (Object o : queryResults) {
+ try {
+ return this.formatObjectToJsonArray(o, properties).orElseGet( () -> {
+ TREE_FORMAT_LOGGER.warn("Empty Optional returned by 'formatObjectToJsonArray'");
+ return body;
+ });
+ } catch (AAIFormatVertexException e) {
+ TREE_FORMAT_LOGGER.warn("Failed to format vertex, returning a partial list " + LogFormatTools.getStackTop(e));
+ } catch (AAIFormatQueryResultFormatNotSupported e) {
+ TREE_FORMAT_LOGGER.warn("Failed to format result type of the query " + LogFormatTools.getStackTop(e));
+ }
+ }
+ return body;
+ }
+
+ public Optional<JsonArray> formatObjectToJsonArray(Object input, Map<String, List<String>> properties)
+ throws AAIFormatVertexException, AAIFormatQueryResultFormatNotSupported {
+ JsonArray json = new JsonArray();
+ if (input == null)
+ return Optional.of(json);
+ if (input instanceof Tree) {
+ return this.getJsonArrayFromTree((Tree<Object>) input);
+ } else {
+ throw new AAIFormatQueryResultFormatNotSupported();
+ }
+ }
+
+ protected Optional<JsonArray> getJsonArrayFromTree(Tree<Object> tree) throws AAIFormatVertexException {
+ if (tree.isEmpty()) {
+ return Optional.of(new JsonArray());
+ }
+
+ // DSL Query
+ JsonArray jsonArray = new JsonArray();
+ JsonObject jsonObject = new JsonObject();
+ for (Map.Entry<Object, Tree<Object>> entry : tree.entrySet()) {
+ Object o = entry.getKey();
+
+ // DSL Query
+ if (o instanceof BulkSet) {
+ BulkSet bs = (BulkSet) o;
+ for (Object o1 : bs) {
+ Optional<JsonObject> obj = this.getJsonFromVertex((Vertex) o1);
+ if (obj.isPresent()) {
+ jsonObject = obj.get();
+ for (Map.Entry<String, JsonElement> mapEntry : jsonObject.entrySet()) {
+ JsonElement jsonRootElementContents = mapEntry.getValue(); // getting everyObject inside
+ if (jsonRootElementContents != null && jsonRootElementContents.isJsonObject()) {
+ JsonObject relatedJsonNode = (JsonObject) jsonRootElementContents;
+ addRelatedNodesToJsonObject(
+ jsonRootElementContents.getAsJsonObject(),
+ getRelatedNodes(relatedJsonNode)
+ );
+ }
+ }
+ jsonArray.add(jsonObject);
+ }
+ }
+ }
+ // Gremlin Query
+ else if (o instanceof Vertex) {
+ Optional<JsonObject> obj = this.getJsonFromVertex((Vertex) o);
+ if (obj.isPresent()) {
+ jsonObject = obj.get();
+ for (Map.Entry<String, JsonElement> mapEntry : jsonObject.entrySet()) {
+ JsonElement jsonRootElementContents = mapEntry.getValue();
+ if (jsonRootElementContents != null && jsonRootElementContents.isJsonObject()) {
+ addRelatedNodesToJsonObject(
+ jsonRootElementContents.getAsJsonObject(),
+ getRelatedNodes(entry.getValue()));
+ }
+ }
+ jsonArray.add(jsonObject);
+ }
+ }
+ }
+ return Optional.of(jsonArray);
+ }
+
+ protected Optional<JsonArray> getRelatedNodes(JsonObject jsonObj) throws AAIFormatVertexException {
+ JsonArray relatedNodes = new JsonArray();
+ for (Map.Entry<String, JsonElement> mapEntry : jsonObj.entrySet()) {
+ String s = mapEntry.getKey();
+ JsonElement jsonRootElementContents = jsonObj.get(s);
+ if (jsonRootElementContents != null && jsonRootElementContents.isJsonObject()) {
+ JsonObject relatedJsonNode = jsonRootElementContents.getAsJsonObject();
+ addRelatedNodesToJsonObject(
+ relatedJsonNode,
+ this.getRelatedNodes(relatedJsonNode)
+ );
+ relatedNodes.add(relatedJsonNode);
+ }
+ }
+ return Optional.of(relatedNodes);
+ }
+
+ protected Optional<JsonArray> getRelatedNodes(Tree<Object> tree) throws AAIFormatVertexException {
+ JsonArray relatedNodes = new JsonArray();
+ for (Map.Entry<Object, Tree<Object>> entry : tree.entrySet()) {
+ Object o = entry.getKey();
+
+ if (o instanceof Vertex) {
+ processVertex(relatedNodes, entry, (Vertex) o);
+ }
+ }
+ return Optional.of(relatedNodes);
+ }
+
+ private void processVertex(JsonArray relatedNodes, Entry<Object, Tree<Object>> entry, Vertex o)
+ throws AAIFormatVertexException {
+ Optional<JsonObject> obj = this.getJsonFromVertex(o);
+ if (obj.isPresent()) {
+ JsonObject jsonObj = obj.get();
+ for (Entry<String, JsonElement> mapEntry : jsonObj.entrySet()) {
+ JsonElement jsonRootElementContents = mapEntry.getValue();
+ if (jsonRootElementContents != null && jsonRootElementContents.isJsonObject()) {
+ JsonObject jsonObject = addRelatedNodesToJsonObject(
+ jsonRootElementContents.getAsJsonObject(),
+ getRelatedNodes(entry.getValue()));
+ relatedNodes.add(jsonObject);
+ }
+ }
+ }
+ }
+
+
+ private static JsonObject addRelatedNodesToJsonObject(JsonObject jsonObject, Optional<JsonArray> relatedNodesOpt) {
+ relatedNodesOpt.ifPresent( relatedNodes -> {
+ if (relatedNodes.size() > 0) {
+ jsonObject.add("related-nodes", relatedNodes);
+ }
+ });
+
+ return jsonObject;
+ }
+
+ /**
+ *
+ * Returns an Optional<JsonObject> to convert the contents from the given Vertex object into a JsonObject.
+ * The fields returned are to record the time stamp of the creation/modification of the object, the user responsible
+ * for
+ * the change, and the last http method performed on the object.
+ *
+ * @param v
+ * @return
+ * @throws AAIFormatVertexException
+ */
+ @Override
+ protected Optional<JsonObject> getJsonFromVertex(Vertex v) throws AAIFormatVertexException {
+
+ JsonObject json = new JsonObject();
+
+ Optional<JsonObject> jsonObject = this.vertexToJsonObject(v);
+ if (jsonObject.isPresent()) {
+ json.add(v.<String>property(AAIProperties.NODE_TYPE).orElse(null), jsonObject.get());
+ } else {
+ return Optional.empty();
+ }
+ return Optional.of(json);
+ }
+
+ protected Optional<JsonObject> vertexToJsonObject(Vertex v) throws AAIFormatVertexException {
+ try {
+ final Introspector obj =
+ getLoader().introspectorFromName(v.<String>property(AAIProperties.NODE_TYPE).orElse(null));
+
+ final List<Vertex> wrapper = new ArrayList<>();
+
+ wrapper.add(v);
+
+ try {
+ getSerializer().dbToObject(wrapper, obj, this.depth, this.nodesOnly, "false");
+ } catch (AAIException | UnsupportedEncodingException e) {
+ throw new AAIFormatVertexException(
+ "Failed to format vertex - error while serializing: " + e.getMessage(), e);
+ }
+
+ final String json = obj.marshal(false);
+
+ return Optional.of(getParser().parse(json).getAsJsonObject());
+ } catch (AAIUnknownObjectException e) {
+ return Optional.empty();
+ }
+ }
+
+ private Loader getLoader() {
+ return loader;
+ }
+
+ private DBSerializer getSerializer() {
+ return serializer;
+ }
+
+ private JsonParser getParser() {
+ return parser;
+ }
+
+
+ @Override
+ protected Optional<JsonObject> getJsonFromVertex(Vertex input, Map<String, List<String>> properties) throws AAIFormatVertexException {
+ return Optional.empty();
+ }
+}
}
public UrlBuilder(SchemaVersion version, DBSerializer serializer, String serverBase, SchemaVersions schemaVersions,
- String basePath) {
+ String basePath) throws AAIException {
this.serializer = serializer;
this.version = version;
- this.serverBase = serverBase;
+ if(serverBase == null){
+ this.serverBase = getServerBase();
+ } else {
+ this.serverBase = serverBase;
+ }
this.schemaVersions = schemaVersions;
if (!basePath.endsWith("/")) {
this.basePath = basePath + "/";
ctx = SSLContext.getInstance("TLSv1.2");
KeyManagerFactory kmf = null;
- try {
+
+ try(FileInputStream fin = new FileInputStream(keystorePath)) {
kmf = KeyManagerFactory.getInstance("SunX509");
- FileInputStream fin = new FileInputStream(keystorePath);
KeyStore ks = KeyStore.getInstance("PKCS12");
char[] pwd = keystorePassword.toCharArray();
ks.load(fin, pwd);
public class RestController implements RestControllerInterface {
private static final String TARGET_NAME = "AAI";
- private static Logger LOGGER = LoggerFactory.getLogger(RestController.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(RestController.class);
private static Client client = null;
public static final String REST_APIPATH_LOGICALLINKS = "network/logical-links/";
public static final String REST_APIPATH_LOGICALLINK = "network/logical-links/logical-link/";
- public RestController() throws AAIException {
- this.initRestClient();
- }
-
public RestController(String truststorePath, String truststorePassword, String keystorePath, String keystorePassword) throws AAIException {
this.initRestClient(truststorePath, truststorePassword, keystorePath, keystorePassword);
}
- /**
- * Inits the rest client.
- *
- * @throws AAIException the AAI exception
- */
- public void initRestClient() throws AAIException {
- if (client == null) {
- try {
- client = getHttpsAuthClient();
- } catch (KeyManagementException e) {
- throw new AAIException("AAI_7117", "KeyManagementException in REST call to DB: " + e.toString());
- } catch (Exception e) {
- throw new AAIException("AAI_7117", " Exception in REST call to DB: " + e.toString());
- }
- }
- }
/**
* Inits the rest client.
*
+ cres.getEntity(String.class));
}
}
+
+ /**
+ * Put.
+ *
+ * @param <T> the generic type
+ * @param t the t
+ * @param sourceID the source ID
+ * @param transId the trans id
+ * @param path the path
+ * @param apiVersion version number
+ * @throws AAIException the AAI exception
+ */
+ public <T> void Put(T t, String sourceID, String transId, String path, String apiVersion)
+ throws AAIException {
+ String methodName = "Put";
+ String url = "";
+ transId += ":" + UUID.randomUUID().toString();
+
+ LOGGER.debug(methodName + " start");
+
+ url = AAIConfig.get(AAIConstants.AAI_SERVER_URL_BASE) + apiVersion + "/" + path;
+
+ ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
+ .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json").entity(t)
+ .put(ClientResponse.class);
+
+ // System.out.println("cres.tostring()="+cres.toString());
+
+ int statuscode = cres.getStatus();
+ if (statuscode >= 200 && statuscode <= 299) {
+ LOGGER.debug(methodName + ": url=" + url + ", request=" + path);
+ } else {
+ throw new AAIException("AAI_7116", methodName + " with status=" + statuscode + ", url=" + url + ", msg="
+ + cres.getEntity(String.class));
+ }
+ }
public void Delete(String sourceID, String transId, String path) throws AAIException {
Delete(sourceID, transId, path, AAIConstants.AAI_RESOURCES_PORT);
import org.junit.Test;
import org.onap.aai.AAISetup;
import org.onap.aai.setup.SchemaVersion;
+import org.springframework.test.annotation.DirtiesContext;
import java.util.List;
import java.util.Map;
import java.util.Properties;
+@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
public class ListEndpointsTest extends AAISetup {
private Properties properties;
-/**
+/*
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
}
@Test
- public void getRealtimeInstanceConnectionName() throws Exception {
+ public void getRealtimeInstanceConnectionName() {
JanusGraphManagement graphMgt = AAIGraph.getInstance().getGraph().openManagement();
String connectionInstanceName =
@Ignore("Need to create schema specific to the test")
@Test
- public void checkIndexOfAliasedIndexedProps() throws Exception {
+ public void checkIndexOfAliasedIndexedProps() {
Set<String> aliasedIndexedProps = getAliasedIndexedProps();
JanusGraphManagement graphMgt = AAIGraph.getInstance().getGraph().openManagement();
for (String aliasedIndexedProp : aliasedIndexedProps) {
public void getVertexPropertiesTest() throws AAIException, UnsupportedEncodingException {
engine.startTransaction();
- Vertex cr =
- engine.tx().addVertex("aai-node-type", "cloud-region", "cloud-owner", "me", "cloud-region-id", "123");
+ Vertex gvnf = engine.tx().addVertex("aai-node-type", "generic-vnf", "vnf-id", "myvnf", "aai-uri",
+ "/network/generic-vnfs/generic-vnf/myvnf",
+ AAIProperties.AAI_UUID, UUID.randomUUID().toString(),
+ AAIProperties.CREATED_TS, 123L,
+ AAIProperties.SOURCE_OF_TRUTH, "sot",
+ AAIProperties.RESOURCE_VERSION, "123",
+ AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot",
+ AAIProperties.LAST_MOD_TS, 333L);
+ Vertex vnfc = engine.tx().addVertex("aai-node-type", "vnfc", "vnfc-name", "a-name", "aai-uri",
+ "/network/vnfcs/vnfc/a-name",
+ AAIProperties.AAI_UUID, UUID.randomUUID().toString(),
+ AAIProperties.CREATED_TS, 123L,
+ AAIProperties.SOURCE_OF_TRUTH, "sot",
+ AAIProperties.RESOURCE_VERSION, "123",
+ AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot",
+ AAIProperties.LAST_MOD_TS, 333L);
+
+ edgeSer.addEdge(engine.tx().traversal(), gvnf, vnfc);
+
+ Introspector vnf = dbser.getVertexProperties(gvnf);
+ assertEquals("generic-vnf", vnf.getDbName());
+ assertEquals("myvnf", vnf.getValue("vnf-id"));
- Introspector crIntro = dbser.getVertexProperties(cr);
- assertEquals("cloud-region", crIntro.getDbName());
- assertEquals("me", crIntro.getValue("cloud-owner"));
- assertEquals("123", crIntro.getValue("cloud-region-id"));
+ assertFalse(vnf.marshal(false).contains("relationship-list"));
}
"{\"path\":[{\"resource-type\":\"generic-vnf\"},{\"resource-type\":\"vserver\"},{\"resource-type\":\"pserver\"},{\"resource-type\":\"complex\"}]}")
.getAsJsonObject();
private JsonObject expectedAsTreeWithResourceFormat = new JsonParser().parse(
- "{\"results\":[{\"generic-vnf\":{\"vnf-id\":\"vnf-id-1\",\"vnf-name\":\"vnf-name-1\",\"related-nodes\":[{\"vserver\":{\"vserver-id\":\"vserver-id-1\",\"vserver-name\":\"vserver-name-1\",\"related-nodes\":[{\"pserver\":{\"hostname\":\"hostname-1\"}}]}},{\"pserver\":{\"hostname\":\"hostname-2\",\"related-nodes\":[{\"complex\":{\"physical-location-id\":\"physical-location-id-2\",\"country\":\"US\"}}]}}]}}]}")
- .getAsJsonObject();
+ "{\"results\":[{\"generic-vnf\":{\"vnf-id\":\"vnf-id-1\",\"vnf-name\":\"vnf-name-1\",\"related-nodes\":[{\"vserver\":{\"vserver-id\":\"vserver-id-1\",\"vserver-name\":\"vserver-name-1\",\"related-nodes\":[{\"pserver\":{\"hostname\":\"hostname-1\"}}]}},{\"pserver\":{\"hostname\":\"hostname-2\",\"related-nodes\":[{\"complex\":{\"physical-location-id\":\"physical-location-id-2\",\"country\":\"US\"}}]}}]}}]}")
+ .getAsJsonObject();
private JsonObject expectedAsTreeWithSimpleFormat = new JsonParser().parse(
"{\"results\":[{\"id\":\"0\",\"node-type\":\"generic-vnf\",\"url\":null,\"properties\":{\"vnf-id\":\"vnf-id-1\",\"vnf-name\":\"vnf-name-1\"},\"related-to\":[{\"id\":\"1\",\"relationship-label\":\"tosca.relationships.HostedOn\",\"node-type\":\"vserver\",\"url\":null},{\"id\":\"5\",\"relationship-label\":\"tosca.relationships.HostedOn\",\"node-type\":\"pserver\",\"url\":null}],\"related-nodes\":[{\"id\":\"1\",\"node-type\":\"vserver\",\"url\":null,\"properties\":{\"vserver-id\":\"vserver-id-1\",\"vserver-name\":\"vserver-name-1\"},\"related-to\":[{\"id\":\"0\",\"relationship-label\":\"tosca.relationships.HostedOn\",\"node-type\":\"generic-vnf\",\"url\":null},{\"id\":\"2\",\"relationship-label\":\"tosca.relationships.HostedOn\",\"node-type\":\"pserver\",\"url\":null}],\"related-nodes\":[{\"id\":\"2\",\"node-type\":\"pserver\",\"url\":null,\"properties\":{\"hostname\":\"hostname-1\"},\"related-to\":[{\"id\":\"1\",\"relationship-label\":\"tosca.relationships.HostedOn\",\"node-type\":\"vserver\",\"url\":null},{\"id\":\"3\",\"relationship-label\":\"org.onap.relationships.inventory.LocatedIn\",\"node-type\":\"complex\",\"url\":null}]}]},{\"id\":\"5\",\"node-type\":\"pserver\",\"url\":null,\"properties\":{\"hostname\":\"hostname-2\"},\"related-to\":[{\"id\":\"0\",\"relationship-label\":\"tosca.relationships.HostedOn\",\"node-type\":\"generic-vnf\",\"url\":null},{\"id\":\"6\",\"relationship-label\":\"org.onap.relationships.inventory.LocatedIn\",\"node-type\":\"complex\",\"url\":null}],\"related-nodes\":[{\"id\":\"6\",\"node-type\":\"complex\",\"url\":null,\"properties\":{\"physical-location-id\":\"physical-location-id-2\",\"country\":\"US\"},\"related-to\":[{\"id\":\"5\",\"relationship-label\":\"org.onap.relationships.inventory.LocatedIn\",\"node-type\":\"pserver\",\"url\":null}]}]}]}]}")
.getAsJsonObject();
--- /dev/null
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-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.aai.serialization.queryformats;
+
+import com.google.gson.JsonObject;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ReadOnlyStrategy;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.T;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
+import org.hamcrest.CoreMatchers;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.onap.aai.AAISetup;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.introspection.ModelType;
+import org.onap.aai.serialization.db.DBSerializer;
+import org.onap.aai.serialization.db.EdgeSerializer;
+import org.onap.aai.serialization.engines.JanusGraphDBEngine;
+import org.onap.aai.serialization.engines.QueryStyle;
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
+import org.onap.aai.serialization.queryformats.utils.UrlBuilder;
+import org.onap.aai.setup.SchemaVersion;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.annotation.DirtiesContext;
+
+import java.util.Optional;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
+public class PathedURLTest extends AAISetup {
+
+ @Mock
+ private UrlBuilder urlBuilder;
+
+ private Graph graph;
+ private TransactionalGraphEngine dbEngine;
+ private Loader loader;
+ private PathedURL pathedURL;
+ private final ModelType factoryType = ModelType.MOXY;
+
+ @Autowired
+ private EdgeSerializer rules;
+
+ private SchemaVersion version;
+ private Vertex pserver;
+ private Vertex complex;
+ private DBSerializer serializer;
+
+ @Before
+ public void setUp() throws Exception {
+
+ version = schemaVersions.getDefaultVersion();
+
+ MockitoAnnotations.initMocks(this);
+
+ graph = TinkerGraph.open();
+
+ Vertex pserver1 =
+ graph.addVertex(
+ T.label, "pserver",
+ T.id, "2",
+ "aai-node-type", "pserver",
+ "hostname", "hostname-1",
+ "resource-version", System.currentTimeMillis()
+ );
+
+ Vertex complex1 = graph.addVertex(T.label, "complex", T.id, "3", "aai-node-type", "complex",
+ "physical-location-id", "physical-location-id-1", "country", "US");
+
+ GraphTraversalSource g = graph.traversal();
+ rules.addEdge(g, pserver1, complex1);
+
+ pserver = pserver1;
+ complex = complex1;
+
+ System.setProperty("AJSC_HOME", ".");
+ System.setProperty("BUNDLECONFIG_DIR", "src/test/resources/bundleconfig-local");
+
+ createLoaderEngineSetup();
+ }
+
+ private void createLoaderEngineSetup() throws AAIException {
+
+ if (loader == null) {
+ loader = loaderFactory.createLoaderForVersion(factoryType, version);
+ dbEngine = spy(new JanusGraphDBEngine(QueryStyle.TRAVERSAL, loader));
+ serializer = new DBSerializer(version, dbEngine, factoryType, "Junit");
+
+ TransactionalGraphEngine.Admin spyAdmin = spy(dbEngine.asAdmin());
+
+ when(dbEngine.tx()).thenReturn(graph);
+ when(dbEngine.asAdmin()).thenReturn(spyAdmin);
+
+ when(spyAdmin.getReadOnlyTraversalSource())
+ .thenReturn(graph.traversal().withStrategies(ReadOnlyStrategy.instance()));
+ when(spyAdmin.getTraversalSource()).thenReturn(graph.traversal());
+ }
+ }
+
+ @Test
+ public void testPathedUrlReturnsResourceVersionWhenSet() throws AAIFormatVertexException, AAIException {
+
+ pathedURL = new PathedURL.Builder(loader, serializer, urlBuilder).includeUrl().build();
+ when(urlBuilder.pathed(pserver)).thenReturn("/aai/v14/cloud-infrastructure/pservers/pserver/hostname-1");
+ Optional<JsonObject> jsonObjectOptional = pathedURL.getJsonFromVertex(pserver);
+
+ if(!jsonObjectOptional.isPresent()){
+ fail("Expecting an json object returned from pathed url but returned none");
+ }
+
+ JsonObject pserverObject = jsonObjectOptional.get();
+
+ assertNotNull("Expecting the pserver object to contain resource type", pserverObject.get("resource-type"));
+ assertThat(pserverObject.get("resource-type").getAsString(), CoreMatchers.is("pserver"));
+ assertNotNull("Expecting the pserver object to contain resource link", pserverObject.get("resource-link"));
+ assertThat(pserverObject.get("resource-link").getAsString(), CoreMatchers.is("/aai/v14/cloud-infrastructure/pservers/pserver/hostname-1"));
+ assertNotNull("Expecting the pserver object to contain resource version", pserverObject.get("resource-version"));
+ }
+
+ @Test
+ public void testPathedUrlReturnsResourceVersionWhenIncludeUrlIsNotSet() throws AAIFormatVertexException, AAIException {
+
+ pathedURL = new PathedURL.Builder(loader, serializer, urlBuilder).build();
+ when(urlBuilder.pathed(pserver)).thenReturn("/aai/v14/cloud-infrastructure/pservers/pserver/hostname-1");
+ Optional<JsonObject> jsonObjectOptional = pathedURL.getJsonFromVertex(pserver);
+
+ if(!jsonObjectOptional.isPresent()){
+ fail("Expecting an json object returned from pathed url but returned none");
+ }
+
+ JsonObject pserverObject = jsonObjectOptional.get();
+
+ assertNotNull("Expecting the pserver object to contain resource type", pserverObject.get("resource-type"));
+ assertThat(pserverObject.get("resource-type").getAsString(), CoreMatchers.is("pserver"));
+ assertNotNull("Expecting the pserver object to contain resource link", pserverObject.get("resource-link"));
+ assertThat(pserverObject.get("resource-link").getAsString(), CoreMatchers.is("/aai/v14/cloud-infrastructure/pservers/pserver/hostname-1"));
+ assertNull("Expecting the pserver object to not contain resource version", pserverObject.get("resource-version"));
+ }
+}
createLoaderEngineSetup();
serializer = new DBSerializer(schemaVersions.getAppRootVersion(), dbEngine, factoryType, "Junit");
- FormatFactory ff = new FormatFactory(loader, serializer, schemaVersions, basePath);
+ FormatFactory ff = new FormatFactory(loader, serializer, schemaVersions, basePath, "https://localhost:8447/aai/");
MultivaluedMap mvm = new MultivaluedHashMap();
mvm.add("depth", "0");
Formatter formatter = ff.get(Format.resource, mvm);
createLoaderEngineSetup();
serializer = new DBSerializer(schemaVersions.getRelatedLinkVersion(), dbEngine, factoryType, "Junit");
- FormatFactory ff = new FormatFactory(loader, serializer, schemaVersions, basePath);
+ FormatFactory ff = new FormatFactory(loader, serializer, schemaVersions, basePath, "https://localhost:8447/aai/");
MultivaluedMap mvm = new MultivaluedHashMap();
mvm.add("depth", "0");
Formatter formatter = ff.get(Format.simple, mvm);
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.onap.aai.AAISetup;
+import org.onap.aai.exceptions.AAIException;
import org.onap.aai.serialization.db.DBSerializer;
import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
import org.onap.aai.setup.SchemaVersion;
}
@Test
- public void v11Pathed() throws AAIFormatVertexException {
+ public void v11Pathed() throws AAIFormatVertexException, AAIException {
SchemaVersion version = new SchemaVersion("v11");
UrlBuilder builder = new UrlBuilder(version, serializer, protocolAndHost, schemaVersions, basePath);
String result = builder.pathed(v);
}
@Test
- public void v11Id() {
+ public void v11Id() throws AAIException {
SchemaVersion version = new SchemaVersion("v11");
UrlBuilder builder = new UrlBuilder(version, serializer, protocolAndHost, schemaVersions, basePath);
String result = builder.id(v);
}
@Test
- public void beforeV11Pathed() throws AAIFormatVertexException {
+ public void beforeV11Pathed() throws AAIFormatVertexException, AAIException {
SchemaVersion version = new SchemaVersion("v10");
UrlBuilder builder = new UrlBuilder(version, serializer, protocolAndHost, schemaVersions, basePath);
String result = builder.pathed(v);
}
@Test
- public void beforeV11Id() {
+ public void beforeV11Id() throws AAIException {
SchemaVersion version = new SchemaVersion("v10");
UrlBuilder builder = new UrlBuilder(version, serializer, protocolAndHost, schemaVersions, basePath);
String result = builder.id(v);
<xml-property name="description" value="The URL to the specific resource"/>
</xml-properties>
</xml-element>
+ <xml-element java-attribute="resourceVersion" name="resource-version" type="java.lang.String">
+ <xml-properties>
+ <xml-property name="description" value="The resource version to the specific resource"/>
+ </xml-properties>
+ </xml-element>
</java-attributes>
</java-type>
<xml-property name="description" value="The URL to the specific resource"/>
</xml-properties>
</xml-element>
+ <xml-element java-attribute="resourceVersion" name="resource-version" type="java.lang.String">
+ <xml-properties>
+ <xml-property name="description" value="The resource version to the specific resource"/>
+ </xml-properties>
+ </xml-element>
</java-attributes>
</java-type>
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.
<xml-property name="description" value="The URL to the specific resource"/>
</xml-properties>
</xml-element>
+ <xml-element java-attribute="resourceVersion" name="resource-version" type="java.lang.String">
+ <xml-properties>
+ <xml-property name="description" value="The resource version to the specific resource"/>
+ </xml-properties>
+ </xml-element>
</java-attributes>
</java-type>
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.
<xml-property name="description" value="The URL to the specific resource"/>
</xml-properties>
</xml-element>
+ <xml-element java-attribute="resourceVersion" name="resource-version" type="java.lang.String">
+ <xml-properties>
+ <xml-property name="description" value="The resource version to the specific resource"/>
+ </xml-properties>
+ </xml-element>
</java-attributes>
</java-type>
<xml-property name="description" value="The URL to the specific resource"/>
</xml-properties>
</xml-element>
+ <xml-element java-attribute="resourceVersion" name="resource-version" type="java.lang.String">
+ <xml-properties>
+ <xml-property name="description" value="The resource version to the specific resource"/>
+ </xml-properties>
+ </xml-element>
</java-attributes>
</java-type>
private static final String TARGET_ENTITY = "DMaaP";
public AaiDmaapMetricLog() {
+ if(MDC.get(ONAPLogConstants.MDCs.SERVER_FQDN) == null) {
+ setServerFQDN();
+ }
}
public void pre(String targetServiceName, String event, String transactionId, String serviceName) {
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Properties;
-import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
private static final String PASSPHRASSES_FILENAME = ".passphrases";
private static final String PASSWORD_FILENAME = ".password";
private static final String TRUSTSTORE_PASSWORD_PROP_NAME = "cadi_truststore_password";
- private static final String SERVER_SSL_KEYSTORE_PROP_NAME = "server.ssl.key-store";
- private static final String SERVER_SSL_KEYSTORE_PKCS12_PROP_NAME = "server.ssl.key-store.pkcs12";
- private static final String SERVER_SSL_TRUSTSTORE_PROP_NAME = "server.ssl.trust-store";
+ public static final String SERVER_SSL_KEYSTORE_PROP_NAME = "server.ssl.key-store";
+ public static final String SERVER_SSL_KEYSTORE_PKCS12_PROP_NAME = "server.ssl.key-store.pkcs12";
+ public static final String SERVER_SSL_TRUSTSTORE_PROP_NAME = "server.ssl.trust-store";
+ public static final String TRUSTSTORE_PASSWORD_NAME = "server.ssl.trust-store-password";
+ public static final String KEYSTORE_PASSWORD_NAME = "server.ssl.key-store-password";
private static Properties serverProps;
private static boolean propsInitialized = false;
private static String TRUSTSTORE_PASSWORD = null;
* @throws AAIException the AAI exception
*/
public synchronized static void init() {
- /*LoggingContext.save();
- LoggingContext.component("config");
- LoggingContext.partnerName("NA");
- LoggingContext.targetEntity("AAI");
- LoggingContext.requestId(UUID.randomUUID().toString());
- LoggingContext.serviceName("AAI");
- LoggingContext.targetServiceName("init");
- LoggingContext.statusCode(StatusCode.COMPLETE);*/
LOGGER.info("Initializing AAIApplicationConfig");
-
AAIApplicationConfig.reloadConfig();
-
- //LoggingContext.restore();
}
/**
catch (AAIException e) {
return null;
}
+ return (retrieveKeystorePasswordWithCertPath(certPath));
+ }
+ /**
+ * Retrieve the keystore password
+ *
+ * @return the password
+ */
+ private static String retrieveKeystorePasswordWithCertPath(String certPath) {
File passwordFile = null;
InputStream passwordStream = null;
}
return keystorePassword;
}
-
/**
* Get the keystore password
*
public static String getKeystorePassword() {
return (KEYSTORE_PASSWORD);
}
-
/**
* Gets the truststore password
*
* @return the password
*/
- private static String retrieveTruststorePassword() {
- String certPath = serverProps.getProperty(SERVER_CERTS_LOCATION_PROP_NAME);
- if (certPath == null) {
- return null;
- }
- try {
- certPath = replaceProperties(certPath);
- }
- catch (AAIException e) {
- return null;
- }
+ private static String retrieveTruststorePasswordWithCertPath(String certPath) {
+
File passphrasesFile = null;
InputStream passphrasesStream = null;
String truststorePassword = null;
return truststorePassword;
}
+ /**
+ * Gets the truststore password
+ *
+ * @return the password
+ */
+ private static String retrieveTruststorePassword() {
+ String certPath = serverProps.getProperty(SERVER_CERTS_LOCATION_PROP_NAME);
+ if (certPath == null) {
+ return null;
+ }
+ try {
+ certPath = replaceProperties(certPath);
+ }
+ catch (AAIException e) {
+ return null;
+ }
+ return (retrieveTruststorePasswordWithCertPath(certPath));
+ }
/**
* Get the trustore password
m.appendTail(sb);
return(sb.toString());
}
+
+ public static Properties retrieveKeystoreProps() throws AAIException {
+
+ Properties props = new Properties();
+ String truststorePath = System.getProperty(SERVER_SSL_TRUSTSTORE_PROP_NAME);
+ String truststorePassword = System.getProperty(TRUSTSTORE_PASSWORD_NAME);
+ String keystorePath = System.getProperty(SERVER_SSL_KEYSTORE_PKCS12_PROP_NAME);
+ String keystorePassword = System.getProperty(KEYSTORE_PASSWORD_NAME);
+ String certLocation = System.getProperty(SERVER_CERTS_LOCATION_PROP_NAME);
+
+ if (truststorePath == null || truststorePath.isEmpty()){
+ truststorePath = AAIApplicationConfig.getTruststore();
+ }
+ if (truststorePath != null) {
+ props.setProperty(SERVER_SSL_TRUSTSTORE_PROP_NAME, truststorePath);
+ }
+ if (truststorePassword == null || truststorePassword.isEmpty()) {
+ if (certLocation != null && (!certLocation.isEmpty())) {
+ truststorePassword = AAIApplicationConfig.retrieveTruststorePasswordWithCertPath(certLocation);
+ }
+ else {
+ truststorePassword = AAIApplicationConfig.getTruststorePassword();
+ }
+
+ }
+ if (truststorePassword != null) {
+ props.setProperty(TRUSTSTORE_PASSWORD_NAME, truststorePassword);
+ }
+ if (keystorePath == null || keystorePath.isEmpty()){
+ keystorePath = AAIApplicationConfig.getKeystorePkcs12();
+ }
+ if (keystorePath != null) {
+ props.setProperty(SERVER_SSL_KEYSTORE_PKCS12_PROP_NAME, keystorePath);
+ }
+ if (keystorePassword == null || keystorePassword.isEmpty()){
+ if (certLocation != null && (!certLocation.isEmpty())) {
+ keystorePassword = AAIApplicationConfig.retrieveKeystorePasswordWithCertPath(certLocation);
+ }
+ else {
+ keystorePassword = AAIApplicationConfig.getKeystorePassword();
+ }
+ }
+ if (keystorePassword != null) {
+ props.setProperty(KEYSTORE_PASSWORD_NAME, keystorePassword);
+ }
+ return(props);
+ }
}
-/**
+/*
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
* as these keys are generated in a couple places, I made a class to contain that logic
*/
public class HbaseSaltPrefixer {
- private int NUM_REGION_BUCKETS = 3; // the number of hbase region servers per cluster
+ // the number of hbase region servers per cluster
+ private static int NUM_REGION_BUCKETS = 3;
private static class SingletonHolder {
private static final HbaseSaltPrefixer INSTANCE = new HbaseSaltPrefixer();
}
- /**
- * Instantiates a new hbase salt prefixer.
- */
private HbaseSaltPrefixer() {
}
- /**
- * Gets the single instance of HbaseSaltPrefixer.
- *
- * @return single instance of HbaseSaltPrefixer
- */
public static HbaseSaltPrefixer getInstance() {
return SingletonHolder.INSTANCE;
}
- /**
- * Prepend salt.
- *
- * @param key the key
- * @return the string
- */
public String prependSalt(String key) {
- int salt = key.hashCode() % NUM_REGION_BUCKETS;
+ int salt = Math.abs(key.hashCode()) % NUM_REGION_BUCKETS;
return salt + "-" + key;
}
}
-/**
+/*
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
LoggingContext.elapsedTime(300, TimeUnit.MILLISECONDS);
assertEquals(MDC.get(LoggingContext.LoggingField.ELAPSED_TIME.toString()), "300");
LoggingContext.init();
- assertTrue(MDC.get(LoggingContext.LoggingField.ELAPSED_TIME.toString()) == null);
+ assertNull(MDC.get(LoggingContext.LoggingField.ELAPSED_TIME.toString()));
}
@Test
public void stopWatchTest() {
assertEquals(testServiceName, MDC.get(LoggingContext.LoggingField.SERVICE_NAME.toString()));
LoggingContext.clear();
- assertTrue(MDC.get(LoggingContext.LoggingField.SERVICE_NAME.toString()) == null);
+ assertNull(MDC.get(LoggingContext.LoggingField.SERVICE_NAME.toString()));
}
assertEquals(testServiceName, MDC.get(LoggingContext.LoggingField.SERVICE_NAME.toString()));
LoggingContext.remove(LoggingContext.LoggingField.SERVICE_NAME.toString());
- assertTrue(MDC.get(LoggingContext.LoggingField.SERVICE_NAME.toString()) == null);
+ assertNull(MDC.get(LoggingContext.LoggingField.SERVICE_NAME.toString()));
}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.onap.aai.aai-common</groupId>
+ <artifactId>aai-parent</artifactId>
+ <version>1.7.0-SNAPSHOT</version>
+ <relativePath>../aai-parent/pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>aai-failover</artifactId>
+
+ <dependencies>
+ <!-- Common logging framework -->
+ <dependency>
+ <groupId>org.onap.aai.logging-service</groupId>
+ <artifactId>common-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-aspects</artifactId>
+ <version>${spring.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.aspectj</groupId>
+ <artifactId>aspectjrt</artifactId>
+ <version>1.9.1</version>
+ </dependency>
+ </dependencies>
+</project>
--- /dev/null
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-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.aai.failover;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.concurrent.atomic.AtomicLong;
+
+@Aspect
+@Component
+public class FailoverAspect {
+
+ private final Logger LOGGER = LoggerFactory.getLogger(FailoverAspect.class);
+
+ private final FailoverMonitor failoverMonitor;
+ private final AtomicLong atomicLong;
+
+ public FailoverAspect(FailoverMonitor failoverMonitor){
+ this.failoverMonitor = failoverMonitor;
+ this.atomicLong = new AtomicLong(1l);
+ }
+
+ /*
+ * By default, check for the existence of the following file: /opt/app/failover/failover.properties
+ *
+ * If the file exists, open the file as properties
+ * and find the following property: is_primary
+ * Check if the following value is set to true
+ * If it is set to true, then proceed with running the scheduled task
+ * and store the current value into an thread safe variable
+ *
+ * If the file doesn't exist, then proceed with the execution of scheduled task
+ * as if it is the primary site since there is nothing helping identify if its primary
+ *
+ * If the application is not in an kubernetes environment, in order to emulate the behavior
+ * search for the file in the classpath of application
+ * If the file can be found then it will behavior similar to above in kubernetes env
+ *
+ * Since some tasks such as ones in history is constantly getting data
+ * with little time in between each runs of the task to get latest data
+ * we don't want to log too much when the failover properties isn't being changed
+ * So it will check the last time this got executed and see if its more than two minutes have passed
+ * then if it did, then it will log current status
+ */
+ @Around("@annotation(org.springframework.scheduling.annotation.Scheduled)")
+ public void preSchedule(ProceedingJoinPoint pointcut) throws Throwable {
+
+ Object target = pointcut.getTarget();
+ MethodSignature signature = (MethodSignature) pointcut.getSignature();
+ String method = signature.getMethod().getName();
+
+ if(failoverMonitor.shouldRun()){
+ atomicLong.set(1l);
+ pointcut.proceed();
+ } else {
+ long currentTime = new Date().getTime();
+ long lastMessageTime = atomicLong.get();
+
+ if((currentTime - lastMessageTime) > 120000){
+ atomicLong.compareAndSet(lastMessageTime, new Date().getTime());
+ LOGGER.debug("Not proceeding the task {}#{} due to is_primary set to false in failover.properties",
+ target.getClass(),
+ method
+ );
+ }
+ }
+ }
+}
+
--- /dev/null
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-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.aai.failover;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Properties;
+
+@Component
+public class FailoverMonitor {
+
+ private static final String IS_PRIMARY = "is_primary";
+ private static final String TRUE = "true";
+ private static final String DEFAULT_FOR_PRIMARY = TRUE;
+
+ @Value("${failover.location:/opt/app/failover/failover.properties}")
+ private String failoverPropertiesPath;
+
+ public boolean shouldRun() throws IOException {
+
+ Path failoverPath = Paths.get(failoverPropertiesPath);
+
+ if(Files.exists(failoverPath)){
+ Properties properties = new Properties();
+ try (InputStream is = Files.newInputStream(failoverPath)){
+ properties.load(is);
+ // If the property is_primary is missing then it should proceed
+ return TRUE.equals(properties.getProperty(IS_PRIMARY, DEFAULT_FOR_PRIMARY));
+ }
+ } else {
+ // If the file doesn't exist, then scheduled task should execute
+ return true;
+ }
+ }
+}
-/**
+/*
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
* 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
- *
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
* 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.
public class ClientType {
public static final String AAI = "aai-rest-client";
+
+ private ClientType() {
+ }
}
* ============LICENSE_END=========================================================
*/
-package org.onap.aai.logging;
+package org.onap.aai.restclient;
-import org.junit.Test;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-public class CustomLogPatternLayoutTest {
-
- /**
- * Test null when defaultConverterMap doesn't have corresponding entry.
- */
- @Test
- public void testNull() {
- String s = CustomLogPatternLayout.defaultConverterMap.get("z");
- assertFalse("Entry not found for key 'z'", CNName.class.getName().equals(s));
- }
-
- /**
- * Test defaultConverterMap when valid entry exists.
- */
- @Test
- public void testEntryFor_Z() {
- CustomLogPatternLayout layout = new CustomLogPatternLayout();
- String s = CustomLogPatternLayout.defaultConverterMap.get("z");
- assertTrue("Entry not found for key 'z'", CNName.class.getName().equals(s));
- }
+public class RestClientTest {
}
package org.onap.aai.schemaif;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
import org.onap.aai.schemaif.definitions.EdgeSchema;
import org.onap.aai.schemaif.definitions.VertexSchema;
+import java.util.Map;
+import java.util.Set;
+
public interface SchemaProvider {
-
+
/**
* Load the schema into memory
*/
- public void loadSchema() throws SchemaProviderException;
-
+ void loadSchema() throws SchemaProviderException;
+
/**
* Get the identifier for the more recent version of the schema
*
* @return The schema version identifier
*/
- public String getLatestSchemaVersion() throws SchemaProviderException;
-
+ String getLatestSchemaVersion() throws SchemaProviderException;
+
/**
* Get the schema definition for a vertex
*
* @param vertexName - Name of the vertex
* @param schemaVersion - Version of the schema to use
- *
+ *
* @return The vertex schema definition
*/
- public VertexSchema getVertexSchema(String vertexName, String schemaVersion) throws SchemaProviderException;
-
+ VertexSchema getVertexSchema(String vertexName, String schemaVersion) throws SchemaProviderException;
+
/**
* Get the schema definition for an edge
*
* @param edgeType - Type of the edge
* @param sourceVertex - The source vertex for the edge
* @param targetVertex - The target vertex for the edge
- * @param schemaVersion - Version of the schema to use
- *
+ * @param version - Version of the schema to use
+ *
* @return The edge schema definition
*/
- public EdgeSchema getEdgeSchema(String edgeType, String sourceVertex, String targetVertex, String version) throws SchemaProviderException;
+ EdgeSchema getEdgeSchema(String edgeType, String sourceVertex, String targetVertex, String version) throws SchemaProviderException;
/**
* Get the list of edge definitions which are adjacent to the given vertex
*
* @param vertexType - Type of the vertex
- * @param schemaVersion - Version of the schema to use
- *
+ * @param version - Version of the schema to use
+ *
* @return The list of edge schema definitions
*/
- public Set<EdgeSchema> getAdjacentEdgeSchema(String vertexType, String version) throws SchemaProviderException;
-
+ Set<EdgeSchema> getAdjacentEdgeSchema(String vertexType, String version) throws SchemaProviderException;
+
/**
* Get the list of edge definitions which are valid for the given source and target
*
* @param sourceType - Type of the source vertex
* @param targetType - Type of the target vertex
- * @param schemaVersion - Version of the schema to use
- *
+ * @param version - Version of the schema to use
+ *
* @return The list of edge schema definitions
*/
- public Set<EdgeSchema> getEdgeSchemaForSourceTarget(String sourceType, String targetType, String version) throws SchemaProviderException;
+ Set<EdgeSchema> getEdgeSchemaForSourceTarget(String sourceType, String targetType, String version) throws SchemaProviderException;
/**
* Get vertex map for a schema version
*
* @param schemaVersion - Version of the schema to use
- *
+ *
* @return The list of vertex types
*/
- public Map<String, VertexSchema> getVertexMap(String schemaVersion) throws SchemaProviderException;
-
+ Map<String, VertexSchema> getVertexMap(String schemaVersion) throws SchemaProviderException;
}
-/**
+/*
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
package org.onap.aai.schemaif.definitions.types;
-import org.onap.aai.schemaif.SchemaProviderException;
-
public abstract class DataType {
public enum Type {
- STRING,
+ STRING,
BOOL,
INT,
LONG,
MAP,
COMPLEX
}
-
- private Type type;
-
+
+ private final Type type;
+
public DataType(Type type) {
this.type = type;
}
public Type getType() {
return type;
}
-
+
public abstract Object validateValue(String value);
-
+
public String toString() {
return getType().toString();
}
-/**
+/*
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
*/
package org.onap.aai.schemaif.json;
-import org.onap.aai.schemaif.SchemaProviderException;
-import org.onap.aai.schemaif.json.definitions.JsonSchema;
-
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
-import com.google.gson.JsonObject;
import com.google.gson.annotations.SerializedName;
+import org.onap.aai.schemaif.SchemaProviderException;
+import org.onap.aai.schemaif.json.definitions.JsonSchema;
public class SchemaServiceResponse {
public static final String SCHEMA_TYPE_OXM = "oxm";
public static final String SCHEMA_TYPE_JSON = "json";
-
+
private static final Gson gson = new GsonBuilder().create();
@SerializedName("schema-version")
private String version;
-
+
@SerializedName("schema-content")
private JsonSchema data;
-
+
public String getVersion() {
return version;
}
if (json == null || json.isEmpty()) {
throw new SchemaProviderException("Empty schema-service response");
}
-
+
return gson.fromJson(json, SchemaServiceResponse.class);
} catch (Exception ex) {
throw new SchemaProviderException("Invalid response from schema service: " + ex.getMessage());
}
}
-
}
-/**
+/*
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
OxmEdgeRulesLoader.loadModels();
OxmSchemaLoader.loadModels();
}
-
+
@Override
public String getLatestSchemaVersion() throws SchemaProviderException {
return OxmSchemaLoader.getLatestVersion();
if (edgeRule == null) {
return null;
}
-
+
FromOxmEdgeSchema es = new FromOxmEdgeSchema();
es.fromEdgeRule(edgeRule);
-
+
return es;
}
@Override
public Set<EdgeSchema> getAdjacentEdgeSchema(String vertexType, String version) throws SchemaProviderException {
RelationshipSchema relSchema = OxmEdgeRulesLoader.getSchemaForVersion(version);
- Set<EdgeSchema> edges = new HashSet<EdgeSchema>();
+ Set<EdgeSchema> edges = new HashSet<>();
List<EdgeRule> rules = relSchema.lookupAdjacentEdges(vertexType);
-
+
for (EdgeRule rule : rules) {
FromOxmEdgeSchema es = new FromOxmEdgeSchema();
es.fromEdgeRule(rule);
edges.add(es);
}
-
+
return edges;
}
-
+
@Override
public Set<EdgeSchema> getEdgeSchemaForSourceTarget(String sourceType, String targetType, String version) throws SchemaProviderException {
RelationshipSchema relSchema = OxmEdgeRulesLoader.getSchemaForVersion(version);
- Set<EdgeSchema> edges = new HashSet<EdgeSchema>();
+ Set<EdgeSchema> edges = new HashSet<>();
Set<String> relTypes = relSchema.getValidRelationTypes(sourceType, targetType);
-
+
for (String type : relTypes) {
EdgeSchema edgeSchema = getEdgeSchema(type, sourceType, targetType, version);
if (edgeSchema != null) {
edges.add(edgeSchema);
}
}
-
+
return edges;
}
-/**
+/*
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
package org.onap.aai.nodes;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.*;
-
-import java.io.*;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-
-import javax.xml.bind.SchemaOutputResolver;
-import javax.xml.transform.*;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
import org.eclipse.persistence.dynamic.DynamicEntity;
import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
import org.junit.Rule;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.onap.aai.config.NodesConfiguration;
-import org.onap.aai.restclient.MockProvider;
import org.onap.aai.setup.SchemaVersion;
import org.onap.aai.testutils.TestUtilConfigTranslator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import org.w3c.dom.Document;
+import javax.xml.bind.SchemaOutputResolver;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Result;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.*;
+
@RunWith(SpringRunner.class)
@TestPropertySource(
properties = {
@Autowired
NodeIngestor nodeIngestor;
- public static void printDocument(Document doc, OutputStream out) throws IOException, TransformerException {
+ public static void printDocument(Document doc, OutputStream out) throws TransformerException {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
- transformer.transform(new DOMSource(doc), new StreamResult(new OutputStreamWriter(out, "UTF-8")));
+ transformer.transform(new DOMSource(doc), new StreamResult(new OutputStreamWriter(out, UTF_8)));
}
@Test
DynamicEntity foo10 = ctx10.newDynamicEntity("Foo");
foo10.set("fooId", "bar");
- assertTrue("bar".equals(foo10.get("fooId")));
+ assertEquals("bar", foo10.get("fooId"));
// should work bc Bar is valid in test_business_v10 schema
DynamicEntity bar10 = ctx10.newDynamicEntity("Bar");
bar10.set("barId", "bar2");
- assertTrue("bar2".equals(bar10.get("barId")));
+ assertEquals("bar2", bar10.get("barId"));
XSDOutputResolver outputResolver10 = new XSDOutputResolver();
ctx10.generateSchema(outputResolver10);
// should work bc Foo.quantity is valid in test_network_v11 schema
DynamicEntity foo11 = ctx11.newDynamicEntity("Foo");
foo11.set("quantity", "12");
- assertTrue("12".equals(foo11.get("quantity")));
+ assertEquals("12", foo11.get("quantity"));
DynamicEntity quux11 = ctx11.newDynamicEntity("Quux");
quux11.set("qManagerName", "some guy");
- assertTrue("some guy".equals(quux11.get("qManagerName")));
+ assertEquals("some guy", quux11.get("qManagerName"));
XSDOutputResolver outputResolver11 = new XSDOutputResolver();
ctx11.generateSchema(outputResolver11);
@Test
public void testGetVersionFromClassName() {
assertEquals(nodeIngestor.getVersionFromClassName("inventory.aai.onap.org.v13.Evc"), new SchemaVersion("v13"));
-
}
@Test
public void testGetVersionFromClassNameNull() {
assertEquals(nodeIngestor.getVersionFromClassName("blah"), new SchemaVersion("v15"));
-
}
@Test
public void testGetObjectsInVersion() {
assertEquals(nodeIngestor.getObjectsInVersion(new SchemaVersion("v13")).size(), 148);
-
}
@Test
assertThat("OXM:\n" + expected, expected, is(content));
}
- private class XSDOutputResolver extends SchemaOutputResolver {
+ private static class XSDOutputResolver extends SchemaOutputResolver {
@Override
public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException {
-/**
+/*
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
package org.onap.aai.nodes;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.*;
-
-import java.io.*;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-
-import javax.xml.bind.SchemaOutputResolver;
-import javax.xml.transform.*;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
import org.eclipse.persistence.dynamic.DynamicEntity;
import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
import org.junit.Rule;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.w3c.dom.Document;
+import javax.xml.bind.SchemaOutputResolver;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Result;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.*;
+
@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(
properties = {
DynamicEntity foo10 = ctx10.newDynamicEntity("Foo");
foo10.set("fooId", "bar");
- assertTrue("bar".equals(foo10.get("fooId")));
+ assertEquals("bar", foo10.get("fooId"));
// should work bc Bar is valid in test_business_v10 schema
DynamicEntity bar10 = ctx10.newDynamicEntity("Bar");
bar10.set("barId", "bar2");
- assertTrue("bar2".equals(bar10.get("barId")));
+ assertEquals("bar2", bar10.get("barId"));
XSDOutputResolver outputResolver10 = new XSDOutputResolver();
ctx10.generateSchema(outputResolver10);
// should work bc Foo.quantity is valid in test_network_v11 schema
DynamicEntity foo11 = ctx11.newDynamicEntity("Foo");
foo11.set("quantity", "12");
- assertTrue("12".equals(foo11.get("quantity")));
+ assertEquals("12", foo11.get("quantity"));
DynamicEntity quux11 = ctx11.newDynamicEntity("Quux");
quux11.set("qManagerName", "some guy");
- assertTrue("some guy".equals(quux11.get("qManagerName")));
+ assertEquals("some guy", quux11.get("qManagerName"));
XSDOutputResolver outputResolver11 = new XSDOutputResolver();
ctx11.generateSchema(outputResolver11);
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
- transformer.transform(new DOMSource(doc), new StreamResult(new OutputStreamWriter(out, "UTF-8")));
+ transformer.transform(new DOMSource(doc), new StreamResult(new OutputStreamWriter(out, UTF_8)));
}
- private class XSDOutputResolver extends SchemaOutputResolver {
+ private static class XSDOutputResolver extends SchemaOutputResolver {
@Override
public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException {
-
- // create new file
- // create stream result
File temp = File.createTempFile("schema", ".xsd");
StreamResult result = new StreamResult(temp);
System.out.println("Schema file: " + temp.getAbsolutePath());
- // set system id
result.setSystemId(temp.toURI().toURL().toString());
- // return result
return result;
}
}
return null;
}
- protected Logger getLogger() {
- return null;
- }
-
}
--- /dev/null
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-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.aai.restclient;
+
+public class RestClientTest {
+
+}
html_last_updated_fmt = '%d-%b-%y %H:%M'
def setup(app):
- app.add_stylesheet("css/ribbon_onap.css")
+ app.add_stylesheet("css/ribbon.css")
With the high volume and variety of data, AAI must be prepared to answer many types of queries; real-time search to quickly retrieve specific items from an ocean of data, relationships to determine impacts and consequences, aggregations and counts to explore availability and consumption, validation and integrity to establish whether systems are acting on good information, history and provenance to reconstruct the current view and its context, and enrichment out to legacy systems to examine the low-level details of the network and virtual assets.
.. image:: images/aai_in_onap.png
+
+AAI Components
+^^^^^^^^^^^^^^
+
+.. image:: images/aai_components.png
+
+ESR
+"""
+Applications for management of external systems.
+
+================== ===
+**aai/esr-gui** External system management ui. UI for esr-server.
+**aai/esr-server** ESR backend, mainly include the function of external system reachable check and data pretreatment.
+================== ===
+
+Input abstraction
+"""""""""""""""""
+Applications that serve as entry points to A&AI.
+
+==================== ===
+**aai/model-loader** Obtains SDC artifacts and loads them into the A&AI Resources service for storage.
+**aai/sparky-be** AAI user interface back end.
+**aai/sparky-fe** AAI user interface front end.
+==================== ===
+
+Query abstraction
+"""""""""""""""""
+Query abstraction point for clients that routes AAI queries and event data.
+
+=================== ===
+**aai/data-router** AAI Microservice used to route AAI queries and event data to correct storage engine. Serves as a query abstraction point for clients, as well as a gateway.
+=================== ===
+
+Data management
+"""""""""""""""
+Microservices that facilitate data management of AAI objects.
+
+============================ ===
+**aai/babel** AAI Microservice to generate AAI model XML from SDC TOSCA CSAR artifacts.
+**aai/cacher** Cacher is a generic service that can be used to snapshot json responses, force sync them, sync them periodically, or update them by consuming dmaap events.
+**aai/chameleon** (deprecated) Abstraction service for historical database.
+**aai/champ** Abstraction from underlying graph storage systems that A&AI would interface with.
+**aai/gizmo** (deprecated) CRUD Rest API endpoint for resources and relationships, delivering atomic interactions with the graph for improved scalability.
+**aai/resources** AAI Resources Micro Service providing CRUD REST APIs for inventory resources. This microservice provides the main path for updating and searching the graph - java-types defined in the OXM file for each version of the API define the REST endpoints - for example, the java-type "CloudRegion" in aai-common/aai-schema/src/main/resources/oxm/aai_oxm_v11.xml maps to /aai/v11/cloud-infrastructure/cloud-regions/cloud-region.
+**aai/search-data-service** Abstraction layer for searchengine, supporting queries and updates. Currently supports Elasticsearch, but has also been design with Solr support in mind.
+**aai/spike** (deprecated) Microservice used to generate events describing changes to the graph data.
+**aai/tabular-data-service** (deprecated) Microservice which serves as an abstraction layer to a tabular data store.
+**aai/validation** Microservice used to invoke validation mechanism .
+============================ ===
+
+Graph services
+""""""""""""""
+Set of components, which store, provide or display schemas.
+
+====================== ===
+**aai/graphadmin** Microservice with various functions for graph management.
+**aai/graphgraph** Microservice used to provide view of AAI model, schema and edge rules.
+**aai/schema-service** Application holds and provides specified schema versions.
+**aai/traversal** AAI Traversal Micro Service providing REST APIs for traversal/search of inventory resources. Custom queries (gremin-style traversals) model based queries (which use a model either manually created or loaded from SDC models) and named-queries (traversals which ignore edge labels and direction and just link together objects of given node types from a starting node).
+====================== ===
+
+Libraries
+"""""""""
+Libraries don't run as standalone applications. They contain general functionality, which may be imported and used in other modules.
+
+======================= ===
+**aai/aai-common** This holds the model, annotations and common modules used across the Resources and Traversal micro services. aai/aai-common creates artifacts like aai-core, aai-schema and aai-annotations, which are used by the rest of the microservices and libraries.
+**aai/event-client** Event bus client library.
+**aai/logging-service** AAI common logging library.
+**aai/rest-client** Library for making REST calls.
+**aai/router-core** Library containing the core camel components for the data router.
+======================= ===
+
+Configuration repositories
+""""""""""""""""""""""""""
+Contain several repositories that include various configuration.
+
+=================== ===
+**aai/aai-data** (deprecated) AAI Chef environment files.
+**aai/aai-config** (deprecated) AAI Chef cookbooks.
+**aai/aai-service** (deprecated) AAI REST based services.
+**aai/oom**
+**aai/test-config** Repository containing test configuration for use in continuous integration.
+=================== ===
:widths: 60,60
"html doc", "yaml doc"
- ":download:`link <https://wiki.onap.org/download/attachments/58229560/aai_swagger_v16.html?api=v2>`", ":download:`link <https://wiki.onap.org/download/attachments/58229560/aai_swagger_v16.yaml?api=v2>`"
+ ":download:`link <https://wiki.onap.org/download/attachments/79201851/aai_swagger_v19.html?api=v2>`", ":download:`link <https://wiki.onap.org/download/attachments/79201851/aai_swagger_v19.yaml?api=v2>`"
AAI Release Notes
==================
-Version: 5.0.2
+Abstract
+========
+
+This document provides release notes for the Active and Available Inventory Project's Frankfurt Release
+
+Release Data
+============
+
+Version: 6.0.0
+--------------
+
+:Release Date: 2020-06-04 (TBD)
+
+New Features
+------------
+
+The R6 Frankfurt release of ONAP includes updates to both use cases and non-functional requirements. AAI is serving v19 as the latest version of the REST APIs, and has support for v16 (Dublin and El Alto).
+
+- Implemented new parent POM under org.onap.aai.aai-common.aai-parent for simplified management of 3rd party dependencies
+- Upgrade to spring-boot 2 (partially complete)
+- Model updates and edge rules changes in support of the following use cases:
+ * CCVPN for SOTN NNI
+ * 5G Network Slicing
+ * Multi-Domain Optical Network Services
+ * PNF enhancements
+- Papyrus XMI UML files for run-time data model reverse engineering
+- Integration with sonarcloud
+- All containers run as non-root user
+
+champ, spike, and gizmo are deprecated and removed from the helm chart. This will be the last release where aai manages its own helm chart, in R7 Guilin and beyond, the aai/oom submodule will be merged back into the oom project.
+
+Known Limitations, Issues, and Workarounds
+==========================================
+
+Known Issues
+------------
+
+* `AAI-2766 <https://jira.onap.org/browse/AAI-2766>`_ - AAI data-router cannot communicate with DMaaP message router service
+* `AAI-2905 <https://jira.onap.org/browse/AAI-2905>`_ - AAI sparky cannot communicate with portal due to certificate issue, might be related to https://jira.onap.org/browse/PORTAL-875
-:Release Data: 2019-10-03
+The AAI sub-project External System Registry (ESR) is re-using elalto containers. The integration team has helped ESR to meet security requirements for Frankfurt, and the AAI is grateful for the contribution.
+
+Workarounds
+-----------
+
+Roles for sparky are loaded into AAF by default, so previous workaround is no longer required. However, the pods cannot resolve portal.api.simpledemo.onap.org anymore, so it's necessary to add an entry to /etc/hosts in the sparky-be pod. This will get around the "unknown host" issue, but then it's leads to AAI-2905, where AAI cannot get the roles from Portal due to the issue with the AAF auto-created certificate.
+
+The community has been unable to make data-router communicate with DMaaP, we welcome contributors who can help resurrect this service, or it will be deprecated in Guilin.
+
+References
+==========
+
+Quick links:
+
+- `AAI project page <https://wiki.onap.org/display/DW/Active+and+Available+Inventory+Project>`_
+- `Passing Badge information for AAI <https://bestpractices.coreinfrastructure.org/en/projects/1591>`_
+
+For more information on the ONAP Frankfurt release, please see:
+
+#. `ONAP Home Page`_
+#. `ONAP Documentation`_
+#. `ONAP Release Downloads`_
+#. `ONAP Wiki Page`_
+
+.. _`ONAP Home Page`: https://www.onap.org
+.. _`ONAP Wiki Page`: https://wiki.onap.org
+.. _`ONAP Documentation`: https://docs.onap.org
+.. _`ONAP Release Downloads`: https://git.onap.org
+
+Version: 5.0.2
+--------------
+:Release Date: 2019-10-03
**New Features**
Version: 1.4.0
+--------------
-:Release Data: 2019-06-08
+:Release Date: 2019-06-08
**New Features**
<module>aai-core</module>
<module>aai-auth</module>
<module>aai-els-onap-logging</module>
+ <module>aai-failover</module>
<module>aai-utils</module>
<module>aai-schema-abstraction</module>
</modules>