diff options
Diffstat (limited to 'ncomp-sirius-manager-server/src')
44 files changed, 8947 insertions, 0 deletions
diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/function/FunctionUtils.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/function/FunctionUtils.java new file mode 100644 index 0000000..926723d --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/function/FunctionUtils.java @@ -0,0 +1,243 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.function; + + + +import org.apache.log4j.Logger; +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.Enumerator; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.json.JSONObject; + +import org.openecomp.ncomp.core.function.*; +import org.openecomp.ncomp.core.types.metrics.MetricAttribute; +import org.openecomp.ncomp.sirius.manager.ManagementServer; +import org.openecomp.ncomp.sirius.manager.Subject; +import org.openecomp.ncomp.sirius.manager.metrics.MetricManager; +import org.openecomp.ncomp.webservice.utils.JsonUtils; + +public class FunctionUtils { + public static final Logger logger = Logger.getLogger(FunctionUtils.class); + + static public EList<ValuePair> evaluate(EObject o, String path, Function function) { + return evaluate(o, path, function); + } + + static public EList<ValuePair> evaluate(EObject o, String path, Function function, boolean debug) { + EList<ValuePair> res = new BasicEList<ValuePair>(); + for (EObject o1 : ManagementServer.findAll(o, path)) { + StringValuePair v = FunctionFactory.eINSTANCE.createStringValuePair(); + v.setPath(ManagementServer.object2ref(o1)); + v.setValue(evaluate(o1, function, debug)); + if (debug) + System.err.println("match0 " + v.getPath() + " " + v.getValue()); + res.add(v); + } + return res; + } + + static public void update(EObject o, String path, Function function) { + update(o, path, function); + } + + static public void update(EObject o, String path, Function function, boolean debug) { + for (EObject o1 : ManagementServer.findAll(o, path)) { + if (debug) + System.err.println("update0 " + ManagementServer.object2ref(o1)); + update(o1, function, debug); + } + } + + public static void update(Object o, Function function, boolean debug) { + if (function instanceof RuleUpdateFunction) { + RuleUpdateFunction e1 = (RuleUpdateFunction) function; + for (FunctionUpdateRule r : e1.getRules()) { + if (match(o, r.getMatches(), debug)) { + if (debug) { + System.err.println("match7 " + o + " matched " + r.getMatches()); + } + update(o, r.getUpdates(), debug); + return; + } + } + return; + } + throw new RuntimeException("Unsupported Function: " + function.getClass()); + } + + private static void update(Object o, EList<FunctionUpdate> updates, boolean debug) { + for (FunctionUpdate u : updates) { + if (u instanceof FunctionUpdateAttribute) { + FunctionUpdateAttribute u1 = (FunctionUpdateAttribute) u; + path2setValue(o, u1.getPath(), u1.getValue(), debug); + } + } + + } + + public static String evaluate(Object r, Function filter) { + return evaluate(r, filter, false); + } + + static public String evaluate(Object o, Function function, boolean debug) { + if (function instanceof RuleFunction) { + RuleFunction e1 = (RuleFunction) function; + for (FunctionRule r : e1.getRules()) { + if (match(o, r.getMatches(), debug)) + return value(r.getAction()); + } + return null; + } + throw new RuntimeException("Unsupported Function: " + function.getClass()); + } + + private static boolean match(Object o, EList<FunctionMatch> l, boolean debug) { + for (FunctionMatch m : l) { + if (!match(o, m, debug)) + return false; + } + return true; + } + + private static boolean match(Object o, FunctionMatch m, boolean debug) { + if (debug) + System.err.println("match2 " + o + " " + m); + if (m instanceof FunctionMatchAttribute) { + FunctionMatchAttribute m1 = (FunctionMatchAttribute) m; + Object o1 = path2value(o, m1.getPath(), debug); + if (debug) + System.err.println("match4 " + m1 + " " + o1 + " " + (o1 != null ? o1.getClass() : "NULL")); + if (o1 instanceof String) { + String v = (String) o1; + if (debug) + System.err.println("match5 " + v.matches(m1.getMatch())); + return m1.isNegation() ^ v.matches(m1.getMatch()); + } + if (o1 instanceof Enumerator || o1 instanceof Integer || o1 instanceof Long || o1 instanceof Boolean) { + if (debug) + System.err.println("match6 " + o1.toString().matches(m1.getMatch())); + return m1.isNegation() ^ o1.toString().matches(m1.getMatch()); + } + // TODO need to report error but only one for each find. + return false; + } + if (m instanceof FunctionMatchMetric && o instanceof EObject) { + FunctionMatchMetric m1 = (FunctionMatchMetric) m; + Object o1 = path2value(o, m1.getPath(), debug); + if (debug) + System.err.println("match4m " + m1 + " " + o1 + " " + (o1 != null ? o1.getClass() : "NULL")); + if (o1 instanceof MetricAttribute) { + double v = MetricManager.getValue((EObject) o, m1.getPath(), m1.getOption()); + if (debug) + System.err.println("match4mm " + m1 + " " + v); + if (m1.getLowerBound() != null && m1.getLowerBound() > v) + return m1.isNegation() ^ false; + if (m1.getUpperBound() != null && m1.getUpperBound() < v) + return m1.isNegation() ^ false; + return m1.isNegation() ^ true; + } + return false; + } + if (m instanceof FunctionMatchInstanceOf) { + FunctionMatchInstanceOf m1 = (FunctionMatchInstanceOf) m; + try { + Class<?> cls = Class.forName(m1.getEPackage()); + EPackage ePackage = (EPackage) cls.getDeclaredField("eINSTANCE").get(null); + EClass eClass = (EClass) ePackage.getEClassifier(m1.getEName()); + EObject o1 = (EObject) o; + // if (o1.eClass().getName().contains("Location")) { + // System.err.println("YYYY: " + o1.eClass() + " " + eClass + + // " " + o1.eClass().isInstance(eClass)+ " " + + // eClass.isInstance(o1.eClass()) + // + " " + o1.eClass().getESuperTypes().contains(eClass)); + // System.err.println("YYYY: " + eClass.getESuperTypes()); + // System.err.println("YYYY: " + o1.eClass().getESuperTypes()); + // } + // NOTE o1.eClass().isInstance(eClass); does not seem to work. + return o1.eClass().getEAllSuperTypes().contains(eClass); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("bad class name: " + m1.getEPackage() + "@" + m1.getEName()); + } + } + throw new RuntimeException("Unsupported FunctionMatch: " + m.getClass()); + } + + private static Object path2value(Object o, String path, boolean debug) { + if (o instanceof EObject) { + EObject o1 = (EObject) o; + Subject s1 = ManagementServer.find(o1, path); + if (debug) + System.err.println("match1 " + path + " " + s1); +// if (path.contains("/category")) { +// if (o1 instanceof LogMessageState) { +// LogMessageState o2 = (LogMessageState) o1; +// if (debug) +// System.err.println("match1 " + ManagementServer.ecore2json(o2.getCategory(), 5, null, true).toString(2)); +// } +// if (debug) +// System.err.println("match1 " + o1 + " " + ManagementServer.ecore2json(o1, 5, null, true)); +// } + if (s1 == null || s1.o == null || s1.attr == null) { + // TODO need to report error but only one for each find. + return false; + } + return s1.o.eGet(s1.attr); + } + if (o instanceof JSONObject) { + return JsonUtils.getValue((JSONObject) o, path.substring(1).replace("/", ".")); + } + throw new RuntimeException("Unsupported class: " + o.getClass()); + } + + private static void path2setValue(Object o, String path, String value, boolean debug) { + if (o instanceof EObject) { + EObject o1 = (EObject) o; + Subject s1 = ManagementServer.find(o1, path); + if (debug) + System.err.println("match1 " + path + " " + s1); + if (s1 == null || s1.o == null || s1.attr == null) { + // TODO need to report error but only one for each find. + return; + } + s1.o.eSet(s1.attr, ManagementServer.jsonValue2attrValue(s1.attr.getEAttributeType(), value)); + return; + } + if (o instanceof JSONObject) { + throw new RuntimeException("JSON object not supported object type"); + // return JsonUtils.getValue((JSONObject) o, + // path.substring(1).replace("/", ".")); + } + throw new RuntimeException("Unsupported class: " + o.getClass()); + } + + private static String value(FunctionAction action) { + if (action == null) + throw new RuntimeException("null action"); + return action.getValue(); + } +} + diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/gui/tools/GuiModelUtils.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/gui/tools/GuiModelUtils.java new file mode 100644 index 0000000..3d8049a --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/gui/tools/GuiModelUtils.java @@ -0,0 +1,646 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.gui.tools; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EAnnotation; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; + +import org.openecomp.ncomp.gwt.siriusportal.model.*; +import org.openecomp.ncomp.core.function.IteratorUsingFunction; +import org.openecomp.ncomp.core.logs.*; +import org.openecomp.ncomp.core.types.metrics.*; +import org.openecomp.ncomp.core.metrics.*; +import org.openecomp.ncomp.core.metrics.DoubleMetric; +import org.openecomp.ncomp.sirius.function.FunctionUtils; +import org.openecomp.ncomp.sirius.manager.*; +import org.openecomp.ncomp.sirius.manager.metrics.MetricManager; +import org.openecomp.ncomp.sirius.manager.tableTemplate.*; +import org.openecomp.ncomp.sirius.manager.server.*; +import org.openecomp.ncomp.utils.SortUtil; +import org.openecomp.ncomp.utils.maps.HashMapMapMap; +import org.openecomp.ncomp.webservice.utils.DateUtils; + +public class GuiModelUtils { + public static final Logger logger = Logger.getLogger(GuiModelUtils.class); + static ModelFactory f = ModelFactory.eINSTANCE; + + static GuiTree ecore2GuiTree(EObject ecore, int levels, @SuppressWarnings("rawtypes") Map options) { + GuiTree tree = f.createGuiTree(); + tree.getSections().addAll(ecore2node(ecore, levels, options).getChildren()); + return tree; + } + + @SuppressWarnings("rawtypes") + static void addEcore2GuiTree(GuiTree t, String path, EObject ecore, int levels, Map options) { + Subject s = ManagementServer.find(t, path); + if (s == null || s.o == null) { + logger.warn("Unable to find " + path + " " + t); + return; + } + GuiTreeNode n = (GuiTreeNode) s.o; + addEcore2GuiTree(n, ecore, levels, options); + } + + @SuppressWarnings("rawtypes") + static void addEcore2GuiTree(GuiTreeNode n, EObject ecore, int levels, Map options) { + n.getChildren().addAll(ecore2node(ecore, levels, options).getChildren()); + } + + @SuppressWarnings("rawtypes") + static void addEList2GuiTree(GuiTreeNode n, EList<EObject> l, int levels, Map options) { + for (EObject ecore : l) { + n.getChildren().add(ecore2node(ecore, levels, options)); + } + } + + static GuiTreeNode addNode2GuiTree(GuiTree t, String path, String name) { + Subject s = ManagementServer.find(t, path); + if (s == null || s.o == null) { + logger.warn("Unable to find " + path + " " + t); + return null; + } + GuiTreeNode n = (GuiTreeNode) s.o; + GuiTreeNode n1 = f.createGuiTreeNode(); + n.getChildren().add(n1); + n1.setNodeName(name); + return n1; + } + + @SuppressWarnings("rawtypes") + private static GuiTreeNode ecore2node(EObject ecore, int levels, Map options) { + if (options == null) + options = new HashMap(); + GuiTreeNode n = f.createGuiTreeNode(); + EAttribute attr = (EAttribute) ecore.eClass().getEStructuralFeature("name"); + if (attr != null) { + n.setNodeName((String) ecore.eGet(attr)); + } + if (n.getNodeName() == null) { + n.setNodeName("NONAME"); + } + for (EReference ref : ecore.eClass().getEAllContainments()) { + Map options1 = newOptions(options, ref.getName()); + int levels1 = newLevels(options1, levels); + if (levels1 == 0) + continue; + GuiTreeNode n1 = f.createGuiTreeNode(); + n1.setNodeName(ref.getName()); + n.getChildren().add(n1); + if (ref.isMany()) { + @SuppressWarnings("unchecked") + EList<EObject> l = (EList<EObject>) ecore.eGet(ref); + for (EObject o : l) + n1.getChildren().add(ecore2node(o, levels1, options1)); + } else { + EObject o = (EObject) ecore.eGet(ref); + if (o != null) { + GuiTreeNode nn = ecore2node(o, levels1, options1); + n1.getChildren().addAll(nn.getChildren()); + } + } + } + return n; + } + + @SuppressWarnings("rawtypes") + private static int newLevels(Map options1, int levels) { + return options1.containsKey("LEVELS") ? (Integer) options1.get("LEVELS") : levels - 1; + } + + @SuppressWarnings("rawtypes") + private static Map newOptions(Map options, String name) { + Object o = options.get(name); + if (!(o instanceof Map)) + return new HashMap(); + return (Map) o; + } + + @SuppressWarnings("rawtypes") + public static GuiObject ecore2GuiObject(EObject ecore, int levels, Map options) { + GuiObject n = f.createGuiObject(); + add2GuiObject(n, ecore, levels, options); + return n; + + } + + public static GuiObject addNode2GuiObject(GuiObject o, String name) { + GuiObject n = f.createGuiObject(); + GuiObjectValueObject v = f.createGuiObjectValueObject(); + v.setV(n); + v.setValueName(name); + o.getValues().add(v); + return n; + } + + @SuppressWarnings("rawtypes") + public static void add2GuiObject(GuiObject n, EObject ecore, int levels, Map options) { + if (levels == 0) + return; + if (options == null) + options = new HashMap(); + Date now = new Date(); + for (EAttribute attr : ecore.eClass().getEAllAttributes()) { + if (hasChildWithName(n, attr.getName())) + continue; + Object o = ecore.eGet(attr); + if (o instanceof IncreasingULongMetricAttribute) { + IncreasingULongMetricAttribute m = (IncreasingULongMetricAttribute) o; + // System.err.println("HERE88: " + m); + m.getValue(); + String delay = m.last == null ? "" : " [" + DateUtils.delay2String(now.getTime() - m.last.getTime()) + "]"; + try { + addTimeSeries(n, ecore, attr, Double.toString(m == null ? -999999.9 : m.getValue()) + delay); + } catch (Exception e) { + System.err.println("HERE88: " + m + " " + new Date()); + if (m != null) + System.err.println("HERE88: " + m.getValue()); + ManagementServerUtils.printStackTrace(e); + } + continue; + } + if (o instanceof LongMetricAttribute) { + LongMetricAttribute m = (LongMetricAttribute) o; + if (m.getValue() == null) + continue; + String delay = m.last == null ? "" : " [" + DateUtils.delay2String(now.getTime() - m.last.getTime()) + "]"; + addTimeSeries(n, ecore, attr, Long.toString(m.getValue()) + delay); + continue; + } + if (o instanceof DoubleMetricAttribute) { + DoubleMetricAttribute m = (DoubleMetricAttribute) o; + m.getValue(); + String delay = m.last == null ? "" : " [" + DateUtils.delay2String(now.getTime() - m.last.getTime()) + "]"; + addTimeSeries(n, ecore, attr, Double.toString(m.getValue()) + delay); + continue; + } + if (o instanceof DateMetricAttribute) { + DateMetricAttribute m = (DateMetricAttribute) o; + Long t = m.getValue(); + if (t != null) { + Date d = new Date(t); + DateUtils.delay2String(now.getTime() - t); + addTimeSeries(n, ecore, attr, d.toString() + " " + DateUtils.delay2String(now.getTime() - t)); + continue; + } + } + addString(n, attr.getName(), o == null ? "" : ecore.eGet(attr).toString()); + } + for (EReference ref : ecore.eClass().getEAllReferences()) { + if (ref.isMany()) { + @SuppressWarnings("unchecked") + EList<EObject> l = (EList<EObject>) ecore.eGet(ref); + if (l.size() == 0) { + addString(n, ref.getName(), "Empty"); + continue; + } + if (!ref.isContainment()) { + Map options1 = (Map) options.get(ref.getName()); + int j = 0; + for (EObject o : l) { + if (options1 == null) { + addString(n, ref.getName() + " #" + j++, + "Reference " + o.eClass().getName() + ":" + ManagementServer.object2ref(o)); + continue; + } + // TODO + // int levels1 =options1.containsKey("LEVELS") ? + // (Integer) options1.get("LEVELS") : levels -1; + // add2GuiObject(n1, o, levels1,options1); + } + continue; + } + GuiObjectNamedList n1 = f.createGuiObjectNamedList(); + n1.setValueName(ref.getName()); + n.getValues().add(n1); + int j = 0; + for (EObject o : l) { + GuiNamedObject n2 = f.createGuiNamedObject(); + EAttribute attr = (EAttribute) o.eClass().getEStructuralFeature("name"); + if (attr == null) { + n2.setObjectName("#" + j++); + } else + n2.setObjectName((String) o.eGet(attr)); + add2GuiObject(n2, o, levels - 1, (Map) options.get(ref.getName())); + n1.getObjects().add(n2); + } + } else { + EObject o = (EObject) ecore.eGet(ref); + if (o == null) { + addString(n, ref.getName(), "Null"); + continue; + } + if (!ref.isContainment()) { + Map options1 = (Map) options.get(ref.getName()); + if (options1 == null) { + addString(n, ref.getName(), "Reference " + o.eClass().getName() + ":" + ManagementServer.object2ref(o)); + continue; + } + int levels1 = options1.containsKey("LEVELS") ? (Integer) options1.get("LEVELS") : levels - 1; + if (options1.containsKey("NAME")) { + // Add another level + GuiObjectValueObject n1 = f.createGuiObjectValueObject(); + n.getValues().add(n1); + n1.setValueName((String) options1.get("NAME")); + n1.setV(f.createGuiObject()); + add2GuiObject(n1.getV(), o, levels1, options1); + continue; + } + add2GuiObject(n, o, levels1, options1); + continue; + } + GuiObjectValueObject n1 = f.createGuiObjectValueObject(); + n.getValues().add(n1); + n1.setValueName(ref.getName()); + n1.setV(f.createGuiObject()); + add2GuiObject(n1.getV(), o, levels - 1, (Map) options.get(ref.getName())); + } + } + } + + private static boolean hasChildWithName(GuiObject n, String name) { + for (GuiObjectValue v : n.getValues()) { + if (v.getValueName().equals(name)) + return true; + } + return false; + } + + private static void addTimeSeries(GuiObject n, EObject ecore, EAttribute attr, String v) { + GuiObjectValueTimeSeries t = f.createGuiObjectValueTimeSeries(); + t.setValueName(attr.getName()); + t.setPath(ManagementServer.object2ref(ecore) + "/" + attr.getName()); + t.setV(v); + n.getValues().add(t); + } + + private static void addString(GuiObject n, String name, String v) { + GuiObjectValueString n1 = f.createGuiObjectValueString(); + n1.setV(v); + n1.setValueName(name); + n.getValues().add(n1); + } + + public static void printTree(GuiTree t) { + for (GuiTreeNode n : t.getSections()) { + printTreeNode(n, ""); + } + } + + private static void printTreeNode(GuiTreeNode t, String indent) { + System.out.println(indent + t.getNodeName()); + for (GuiTreeNode n : t.getChildren()) { + printTreeNode(n, " " + indent); + } + } + + public static String attr2unit(EAttribute attr) { + EAnnotation anno = attr.getEAnnotation("http://openecomp.org/sirius/doc"); + if (anno == null) + return ""; + String unit = anno.getDetails().get("unit"); + return unit == null ? "" : unit; + } + + public static GuiTimeSerie getTimeSerie(ManagementServer s, String path, String start, String end, String duration) { + + GuiTimeSerie t = f.createGuiTimeSerie(); + Date start1 = DateUtils.dateFromString(start); + Date end1 = DateUtils.dateFromString(end); + if (duration == null) + duration = ""; + long duration2 = duration.length() > 0 ? DateUtils.stringToDuration(duration) : 0; + if (duration2 > 0) { + start1.setTime(start1.getTime() / duration2 * duration2); + end1.setTime(end1.getTime() / duration2 * duration2 + duration2); + } + MetricsFactory ff = MetricsFactory.eINSTANCE; + AggregationMetricValueOption option = ff.createAggregationMetricValueOption(); + SequenceMetricValueOption seq = ff.createSequenceMetricValueOption(); + seq.getOptions().add(ff.createBasicMetricValueOption()); + seq.getOptions().add(option); + option.setDuration(duration); + option.setAggregationType(AggregationMetricValueOptionType.AVERAGE); + EList<DoubleMetric> values = s.metrics.getValues(path, start1.getTime(), end1.getTime(), seq,false); + Subject s1 = s.find(path); + for (DoubleMetric d : values) { + GuiTimeSerieData dd; + dd = ModelFactory.eINSTANCE.createGuiTimeSerieData(); + dd.setTime(new Date(d.getTime())); + t.getData().add(dd); + dd.setValue(d.getValue()); + } + t.setName(s1.attr.getName()); + t.setXAxisLabel("GMT"); + t.setYAxisLabel(attr2unit(s1.attr)); + return t; + } + + public static GuiTable logsReport(ManagementServer s, String path, Date start, Date end, LogLevel minLogLevel, LogSeverity minLogSeverity) { + System.err.println(path + " " +start + " " +end + " " +minLogLevel + " " +minLogSeverity); + GuiTableUtil table = new GuiTableUtil(); + GuiTableColumn c; + c = table.addColumn("Time", GuiTableColumnType.STRING); + c.setWidth(20); + c = table.addColumn("Level", GuiTableColumnType.STRING); + c.setWidth(10); + c = table.addColumn("Severity", GuiTableColumnType.STRING); + // c.setHidden(true); + c.setWidth(10); + c = table.addColumn("Path", GuiTableColumnType.STRING); + c.setWidth(80); + c = table.addColumn("Message", GuiTableColumnType.STRING); + for (LogMessage m : s.logs.getMessages(path, start, end)) { + if (minLogLevel != LogLevel.UNKNOWN && m.getLevel().ordinal() < minLogLevel.ordinal()) continue; + if (minLogSeverity != LogSeverity.UNKNOWN && (m.getSeverity() == LogSeverity.UNKNOWN || m.getSeverity().ordinal() > minLogSeverity.ordinal())) continue; + table.newRow(); + table.addCellDate(m.getTime()); + table.addCell(m.getLevel().toString()); + table.addCell(m.getSeverity().toString()); + table.addCell(m.getResourceName()); + table.addCell(m.getMessage().replaceFirst("\\[.*?\\] ","").replaceFirst("[a-zA-Z0-9.]*:[0-9]+$","")); + } + return table.getTable(); + } + + public static GuiTable logsReportHourly(ManagementServer s, String path, Date start, Date end, String duration, LogLevel minLogLevel, LogSeverity minLogSeverity) { + long duration2 = DateUtils.stringToDuration(duration); + GuiTableUtil table = new GuiTableUtil(); + GuiTableColumn c; + c = table.addColumn("Last Time", GuiTableColumnType.STRING); + c.setWidth(20); + c = table.addColumn("First Time", GuiTableColumnType.STRING); + c.setWidth(20); + c.setHidden(true); + c = table.addColumn("Level", GuiTableColumnType.STRING); + c.setWidth(10); + c = table.addColumn("Severity", GuiTableColumnType.STRING); + // c.setHidden(true); + c.setWidth(10); + c = table.addColumn("Path", GuiTableColumnType.STRING); + c.setWidth(80); + c = table.addColumn("Number", GuiTableColumnType.DOUBLE); + c.setWidth(15); + c.setFormat("#,##0"); + c = table.addColumn("Message", GuiTableColumnType.STRING); + HashMap<String, List<LogMessage>> map = new HashMap<String, List<LogMessage>>(); + List<LogMessage> firstList = new ArrayList<LogMessage>(); + for (LogMessage m : s.logs.getMessages(path, start, end)) { + if (minLogLevel != LogLevel.UNKNOWN && m.getLevel().ordinal() < minLogLevel.ordinal()) continue; + if (minLogSeverity != LogSeverity.UNKNOWN && (m.getSeverity() == LogSeverity.UNKNOWN || m.getSeverity().ordinal() > minLogSeverity.ordinal())) continue; + String k = messageKey(m, duration2); + List<LogMessage> l = map.get(k); + if (l == null) { + l = new ArrayList<LogMessage>(); + map.put(k, l); + firstList.add(m); + } + l.add(m); + } + for (LogMessage m : firstList) { + List<LogMessage> l = map.get(messageKey(m, duration2)); + LogMessage first = l.get(l.size() - 1); + table.newRow(); + table.addCellDate(m.getTime()); + table.addCellDate(first.getTime()); + table.addCell(m.getLevel().toString()); + table.addCell(m.getSeverity().toString()); + table.addCell(m.getResourceName()); + table.addCell((double) l.size()); + table.addCell(m.getMessage().replaceFirst("\\[.*?\\] ","").replaceFirst("[a-zA-Z0-9.]*:[0-9]+$","")); + } + return table.getTable(); + } + + private static String messageKey(LogMessage m, long duration2) { + String k = m.getResourceName() + ":" + m.getLevel().toString() + ":" + m.getSeverity().toString() + ":" + (m.getTime() / duration2) + + ":" + m.getMessage().replaceAll("Exchange@[0-9a-f]+", "EEE").replaceAll("[0-9]+", "NNN"); + // System.out.println(m.getMessage() + " -> " + k); + return k; + } + + public static void addTree(GuiTreeUtil tree) { + tree.addSection("reports", GuiView.NONE); + tree.addNode("/reports", "logsReport", GuiView.TABLE); + tree.addNode("/reports", "logsReportHourly", GuiView.TABLE); + tree.addNode("/reports", "logsReportDaily", GuiView.TABLE); + } + + public static GuiTable getTable(ManagementServer s, String path, String start, String end) { + AbstractManagementServer c = (AbstractManagementServer) s.getObject(); + for (AbstractTableTemplate t : c.getConfiguration().getTableTemplates()) { + for (EObject o : s.findAll(t.getTreePath())) { + String treePath = ManagementServer.expandPath(o, t.getTablePath(), "$"); + if (treePath.equals(path)) { + if (t instanceof LogTableTemplate) { + LogTableTemplate logTable = (LogTableTemplate) t; + // TODO handle real parameters. + Date start1 = DateUtils.dateFromString(logTable.getDuration()); + Date end1 = new Date(); + if (end1.before(start1)) { + logger.warn("start after end"); + } + String prefix = ManagementServer.expandPath(o, logTable.getPrefixResourcePath(), "$"); + if (logTable.getAggregationDuration() != null) { + return logsReportHourly(s, prefix, start1, end1, logTable.getAggregationDuration(), logTable.getMinLevel(), logTable.getMinSeverity()); + } else { + return logsReport(s, prefix, start1, end1, logTable.getMinLevel(), logTable.getMinSeverity()); + } + } + if (t instanceof TimeTableTemplate) { + return tableFromTimeTemplate(s,o,(TimeTableTemplate) t); + } + if (t instanceof IteratorTableTemplate) { + return tableFromIteratorTableTemplate(s,o,(IteratorTableTemplate) t); + } + if (t instanceof TableTemplate) { + return tableFromTemplate(s,o,(TableTemplate) t); + } + } + } + } + if (path.startsWith("/reports/logsReportHourly")) { + // TODO handle parameters. + return logsReportHourly(s, "", DateUtils.dateFromString("-24hour"), new Date(), "1hour",LogLevel.DEBUG,LogSeverity.SEV4); + } + if (path.startsWith("/reports/logsReportDaily")) { + // TODO handle parameters. + return logsReportHourly(s, "", DateUtils.dateFromString("-7day"), new Date(), "1day",LogLevel.DEBUG,LogSeverity.SEV4); + } + if (path.startsWith("/reports/logsReport")) { + // TODO handle parameters. + return logsReport(s, "", DateUtils.dateFromString("-24hour"), new Date(),LogLevel.DEBUG,LogSeverity.SEV4); + } + throw new RuntimeException("Unable to create table: " + path); + } + + private static GuiTable tableFromIteratorTableTemplate(ManagementServer s, EObject o, IteratorTableTemplate t) { + System.err.println("tableFromTemplate: " + ManagementServer.object2ref(o) + " " + ManagementServer.object2ref(t)); + GuiTableUtil table = new GuiTableUtil(); + addTemplateColumns(table,t); + if (! (t.getIterator() instanceof IteratorUsingFunction)) { + throw new RuntimeException("Unsupported iterator:" + t.getIterator().getClass()); + } + IteratorUsingFunction ii = (IteratorUsingFunction) t.getIterator(); + for (String path : ii.getPaths()) { + for (EObject row : s.findAll(path)) { + if (ii.isRecursive()) { + for (EObject r : ManagementServer.object2containedObjects(row)) { + if (FunctionUtils.evaluate(r, ii.getFilter()).toLowerCase().equals("true")) + tableAddRow(s,r,table,t); + } + } + else { + if (FunctionUtils.evaluate(row, ii.getFilter()).toLowerCase().equals("true")) + tableAddRow(s,row,table,t); + } + } + } + return table.getTable(); + } + + private static void tableAddRow(ManagementServer s, EObject row, GuiTableUtil table, HasColumnsTableTemplate t) { + table.newRow(); + for (TableTemplateColumn col: t.getColumns()) { + if (col instanceof TableTemplateAttributeColumn) { + addAttributeCell(table,row,(TableTemplateAttributeColumn) col); + continue; + } + if (col instanceof TableTemplateMetricColumn) { + TableTemplateMetricColumn col1 = (TableTemplateMetricColumn) col; + Subject s1 = ManagementServer.find(row,col1.getPath()); + if (s1 == null || s1.o == null|| s1.attr == null) { + table.addCell(-5.0); + continue; + } + Object a = s1.o.eGet(s1.attr); + if (a instanceof MetricAttribute) + table.addCell(s.metrics.getValue(row,col1.getPath(),col1.getOption())); + else + table.addCell(-4.0); + continue; + } + table.addCell("??"); + } + + } + + private static GuiTable tableFromTimeTemplate(ManagementServer s, EObject o, TimeTableTemplate t) { + System.err.println("tableFromTemplate: " + ManagementServer.object2ref(o) + " " + ManagementServer.object2ref(t)); + GuiTableUtil table = new GuiTableUtil(); + table.addColumn("Time", GuiTableColumnType.DATE); + addTemplateColumns(table,t); + List<EObject> rows = s.findAll(t.getRowPath()); + HashMapMapMap<Long, TableTemplateColumn, EObject, Double> values = new HashMapMapMap<Long, TableTemplateColumn, EObject, Double>(); + Long end = new Date().getTime(); + Long start = end - DateUtils.stringToDuration(t.getDuration()); + for (EObject row : rows) { + for (TableTemplateColumn col: t.getColumns()) { + if (col instanceof TableTemplateMetricColumn) { + TableTemplateMetricColumn col1 = (TableTemplateMetricColumn) col; + Subject s1 = ManagementServer.find(row,col1.getPath()); + if (s1 == null || s1.o == null|| s1.attr == null) + continue; + Object a = s1.o.eGet(s1.attr); + if (!(a instanceof MetricAttribute)) continue; + for (DoubleMetric d : MetricManager.getValues(row,start, end, col1.getPath(),col1.getOption(),false)){ + values.insert(d.getTime(), col, row, d.getValue()); + } + } + } + } + for (long tt : SortUtil.sort(values.keySet())) { + for (EObject row : rows) { + table.newRow(); + table.addCellDate(tt); + for (TableTemplateColumn col: t.getColumns()) { + if (col instanceof TableTemplateAttributeColumn) { + addAttributeCell(table,row,(TableTemplateAttributeColumn) col); + continue; + } + if (col instanceof TableTemplateMetricColumn) { + Double d = values.get(tt,col,row); + table.addCell(d == null ? -4.0 : d); + continue; + } + table.addCell("??"); + } + } + } + return table.getTable(); + } + + private static void addAttributeCell(GuiTableUtil table, EObject row, TableTemplateAttributeColumn col) { + TableTemplateAttributeColumn col1 = (TableTemplateAttributeColumn) col; + if (col1.getPath().equals("$path")) { + table.addCell(ManagementServer.object2ref(row)); + return; + } + if (col1.getPath().equals("$class")) { + table.addCell(row.eClass().getInstanceClassName()); + return; + } + Subject s1 = ManagementServer.find(row, col1.getPath()); + if (s1 == null || s1.o == null || s1.attr == null) + table.addCell("ERROR"); + else + table.addCell(s1.o.eGet(s1.attr)); + } + + private static void addTemplateColumns(GuiTableUtil table, HasColumnsTableTemplate t) { + for (TableTemplateColumn col: t.getColumns()) { + GuiTableColumn c = null; + if (col instanceof TableTemplateAttributeColumn) { + TableTemplateAttributeColumn col1 = (TableTemplateAttributeColumn) col; + c = table.addColumn(col1.getName(), GuiTableColumnType.STRING); + } + if (col instanceof TableTemplateMetricColumn) { + TableTemplateMetricColumn col1 = (TableTemplateMetricColumn) col; + c = table.addColumn(col1.getName(), GuiTableColumnType.DOUBLE); + } + if (c == null) { + c = table.addColumn(col.getName(), GuiTableColumnType.STRING); + } +// c.setWidth(20); + } + } + + private static GuiTable tableFromTemplate(ManagementServer s, EObject o, TableTemplate t) { + System.err.println("tableFromTemplate: " + ManagementServer.object2ref(o) + " " + ManagementServer.object2ref(t)); + GuiTableUtil table = new GuiTableUtil(); + addTemplateColumns(table,t); + for (EObject row : s.findAll(t.getRowPath())) { + tableAddRow(s,row,table,t); + } + return table.getTable(); + } + +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/gui/tools/GuiObjectUtil.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/gui/tools/GuiObjectUtil.java new file mode 100644 index 0000000..9dc9f6b --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/gui/tools/GuiObjectUtil.java @@ -0,0 +1,274 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.gui.tools; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import org.apache.log4j.Logger; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; + +import org.openecomp.ncomp.core.types.metrics.*; +import org.openecomp.ncomp.sirius.manager.ManagementServer; +import org.openecomp.ncomp.sirius.manager.Subject; +import org.openecomp.ncomp.gwt.siriusportal.model.*; +import org.openecomp.ncomp.webservice.utils.DateUtils; + +public class GuiObjectUtil { + public static final Logger logger = Logger.getLogger(GuiObjectUtil.class); + static ModelFactory f = ModelFactory.eINSTANCE; + + static GuiTree ecore2GuiTree(EObject ecore, int levels, @SuppressWarnings("rawtypes") Map options) { + GuiTree tree = f.createGuiTree(); + tree.getSections().addAll(ecore2node(ecore,levels,options).getChildren()); + return tree; + } + + @SuppressWarnings("rawtypes") + static void addEcore2GuiTree(GuiTree t, String path, EObject ecore, int levels, Map options) { + Subject s = ManagementServer.find(t, path); + if (s == null || s.o == null) { + logger.warn("Unable to find " + path + " " + t); + return; + } + GuiTreeNode n = (GuiTreeNode) s.o; + addEcore2GuiTree(n,ecore,levels,options); + } + @SuppressWarnings("rawtypes") + static void addEcore2GuiTree(GuiTreeNode n, EObject ecore, int levels, Map options) { + n.getChildren().addAll(ecore2node(ecore,levels,options).getChildren()); + } + @SuppressWarnings("rawtypes") + static void addEList2GuiTree(GuiTreeNode n, EList<EObject> l, int levels, Map options) { + for (EObject ecore: l) { + n.getChildren().add(ecore2node(ecore,levels,options)); + } + } + static GuiTreeNode addNode2GuiTree(GuiTree t, String path, String name) { + Subject s = ManagementServer.find(t, path); + if (s == null || s.o == null) { + logger.warn("Unable to find " + path + " " + t); + return null; + } + GuiTreeNode n = (GuiTreeNode) s.o; + GuiTreeNode n1 = f.createGuiTreeNode(); + n.getChildren().add(n1); + n1.setNodeName(name); + return n1; + } + @SuppressWarnings("rawtypes") + private static GuiTreeNode ecore2node(EObject ecore, int levels, Map options) { + if (options == null) options = new HashMap(); + GuiTreeNode n = f.createGuiTreeNode(); + EAttribute attr = (EAttribute) ecore.eClass().getEStructuralFeature("name"); + if (attr != null) { + n.setNodeName((String) ecore.eGet(attr)); + } + if (n.getNodeName() == null) { + n.setNodeName("NONAME"); + } + for (EReference ref : ecore.eClass().getEAllContainments()) { + Map options1 = newOptions(options,ref.getName()); + int levels1 = newLevels(options1,levels); + if (levels1 == 0) continue; + GuiTreeNode n1 = f.createGuiTreeNode(); + n1.setNodeName(ref.getName()); + n.getChildren().add(n1); + if (ref.isMany()) { + @SuppressWarnings("unchecked") + EList<EObject> l = (EList<EObject>) ecore.eGet(ref); + for (EObject o : l) + n1.getChildren().add(ecore2node(o,levels1,options1)); + } else { + EObject o = (EObject) ecore.eGet(ref); + if (o != null) { + GuiTreeNode nn = ecore2node(o,levels1,options1); + n1.getChildren().addAll(nn.getChildren()); + } + } + } + return n; + } + + @SuppressWarnings("rawtypes") + private static int newLevels(Map options1, int levels) { + return options1.containsKey("LEVELS") ? (Integer) options1.get("LEVELS") : levels - 1; + } + + @SuppressWarnings("rawtypes") + private static Map newOptions(Map options, String name) { + Object o = options.get(name); + if (! (o instanceof Map)) return new HashMap(); + return (Map) o; + } + + @SuppressWarnings("rawtypes") + public static GuiObject ecore2GuiObject(EObject ecore, int levels, Map options) { + GuiObject n = f.createGuiObject(); + add2GuiObject(n, ecore, levels, options); + return n; + + } + + public static GuiObject addNode2GuiObject(GuiObject o, String name) { + GuiObject n = f.createGuiObject(); + GuiObjectValueObject v = f.createGuiObjectValueObject(); + v.setV(n); + v.setValueName(name); + o.getValues().add(v); + return n; + } + @SuppressWarnings("rawtypes") + public static void add2GuiObject(GuiObject n, EObject ecore, int levels, Map options) { + if (levels == 0) return; + if (options == null) options = new HashMap(); + for (EAttribute attr : ecore.eClass().getEAllAttributes()) { + Object o = ecore.eGet(attr); + if (o instanceof IncreasingULongMetricAttribute) { + IncreasingULongMetricAttribute m = (IncreasingULongMetricAttribute) o; + addTimeSeries(n,ecore,attr,Double.toString(m == null ? -999999.9 : m.getValue())); + continue; + } + if (o instanceof LongMetricAttribute) { + LongMetricAttribute m = (LongMetricAttribute) o; + addTimeSeries(n,ecore,attr,Long.toString(m.getValue())); + continue; + } + if (o instanceof DoubleMetricAttribute) { + DoubleMetricAttribute m = (DoubleMetricAttribute) o; + addTimeSeries(n,ecore,attr,Double.toString(m.getValue())); + continue; + } + if (o instanceof DateMetricAttribute) { + DateMetricAttribute m = (DateMetricAttribute) o; + long t = m.getValue(); + Date d = new Date(t); + Date now = new Date(); + DateUtils.delay2String(now.getTime()-t); + addTimeSeries(n,ecore,attr,d.toString() + " " + DateUtils.delay2String(now.getTime()-t)); + continue; + } + addString(n,attr.getName(),o == null ? "" : ecore.eGet(attr).toString()); + } + for (EReference ref : ecore.eClass().getEAllReferences()) { + if (ref.isMany()) { + @SuppressWarnings("unchecked") + EList<EObject> l = (EList<EObject>) ecore.eGet(ref); + if (l.size() == 0) { + addString(n,ref.getName(),"Empty"); + continue; + } + if (! ref.isContainment()) { + Map options1 = (Map) options.get(ref.getName()); + for (EObject o : l) { + int j = 0; + if (options1 == null) { + addString(n,ref.getName() + " #" + j, "Reference " + o.eClass().getName() + ":" + ManagementServer.object2ref(o)); + continue; + } +// TODO +// int levels1 =options1.containsKey("LEVELS") ? (Integer) options1.get("LEVELS") : levels -1; +// add2GuiObject(n1, o, levels1,options1); + } + continue; + } + GuiObjectNamedList n1 = f.createGuiObjectNamedList(); + n1.setValueName(ref.getName()); + n.getValues().add(n1); + for (EObject o : l) { + GuiNamedObject n2 = f.createGuiNamedObject(); + EAttribute attr = (EAttribute) o.eClass().getEStructuralFeature("name"); + if (attr == null) { + logger.warn("Class without name: " + o.eClass().getName()); + continue; + } + n2.setObjectName((String) o.eGet(attr)); + add2GuiObject(n2, o, levels-1,(Map) options.get(ref.getName())); + n1.getObjects().add(n2 ); + } + } + else { + EObject o = (EObject) ecore.eGet(ref); + if (o == null) { + addString(n,ref.getName(),"Null"); + continue; + } + if (! ref.isContainment()) { + Map options1 = (Map) options.get(ref.getName()); + if (options1 == null) { + addString(n,ref.getName(),"Reference " + o.eClass().getName() + ":" + ManagementServer.object2ref(o)); + continue; + } + int levels1 = options1.containsKey("LEVELS") ? (Integer) options1.get("LEVELS") : levels -1; + if (options1.containsKey("NAME")) { + // Add another level + GuiObjectValueObject n1 = f.createGuiObjectValueObject(); + n.getValues().add(n1 ); + n1.setValueName((String) options1.get("NAME")); + n1.setV(f.createGuiObject()); + add2GuiObject(n1.getV(), o, levels1,options1); + continue; + } + add2GuiObject(n, o, levels1,options1); + continue; + } + GuiObjectValueObject n1 = f.createGuiObjectValueObject(); + n.getValues().add(n1 ); + n1.setValueName(ref.getName()); + n1.setV(f.createGuiObject()); + add2GuiObject(n1.getV(), o, levels-1,(Map) options.get(ref.getName())); + } + } + } + + private static void addTimeSeries(GuiObject n, EObject ecore, EAttribute attr, String v) { + GuiObjectValueTimeSeries t = f.createGuiObjectValueTimeSeries(); + t.setValueName(attr.getName()); + t.setPath(ManagementServer.object2ref(ecore) + "/" + attr.getName()); + t.setV(v); + n.getValues().add(t); + } + + private static void addString(GuiObject n, String name, String v) { + GuiObjectValueString n1 = f.createGuiObjectValueString(); + n1.setV(v); + n1.setValueName(name); + n.getValues().add(n1); + } + + public static void printTree(GuiTree t) { + for (GuiTreeNode n : t.getSections()) { + printTreeNode(n, ""); + } + } + + private static void printTreeNode(GuiTreeNode t, String indent) { + System.out.println(indent + t.getNodeName()); + for (GuiTreeNode n : t.getChildren()) { + printTreeNode(n, " " + indent); + } + } +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/gui/tools/GuiTableUtil.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/gui/tools/GuiTableUtil.java new file mode 100644 index 0000000..b883442 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/gui/tools/GuiTableUtil.java @@ -0,0 +1,127 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.gui.tools;
+
+import java.util.Date;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import org.openecomp.ncomp.gwt.siriusportal.model.*;
+
+public class GuiTableUtil {
+ static ModelFactory f = ModelFactory.eINSTANCE;
+ GuiTable t;
+ GuiTableRow r = null;
+ public GuiTableUtil() {
+ t = f.createGuiTable();
+ }
+ public GuiTableColumn addColumn(String name, GuiTableColumnType type) {
+ GuiTableColumn c = f.createGuiTableColumn();
+ c.setColName(name);
+ c.setColumnType(type);
+ t.getColumns().add(c);
+ return c;
+ }
+ public void newRow() {
+ if (r != null) {
+ t.getRows().add(r);
+ r = null;
+ }
+ r = f.createGuiTableRow();
+ }
+ public void addCell(Object o) {
+ if (o instanceof Date) {
+ GuiTableCellDate c = f.createGuiTableCellDate();
+ c.setValue((Date) o);
+ r.getCells().add(c);
+ return;
+ }
+ if (o instanceof Integer) {
+ GuiTableCellDouble c = f.createGuiTableCellDouble();
+ Integer i = (Integer) o;
+ c.setValue(i.doubleValue());
+ r.getCells().add(c);
+ return;
+ }
+ GuiTableCellString c = f.createGuiTableCellString();
+ c.setValue(o != null ? o.toString() : "NULL");
+ r.getCells().add(c);
+ }
+ public GuiTable getTable() {
+ if (r != null) t.getRows().add(r);
+ for (GuiTableRow r : t.getRows()) {
+ if (t.getColumns().size() != r.getCells().size())
+ throw new RuntimeException("Wrong number of cells" + t.getColumns().size() + " != " + r.getCells().size());
+ }
+ return t;
+ }
+ public GuiTableCellReferences addCellRef(EObject o, String def) {
+ GuiTableCellReferences res = f.createGuiTableCellReferences();
+ if (o == null) {
+ addCell(def);
+ return res;
+ }
+ addCellRef(res,o,def);
+ // TODO removed when GUI is updated
+ addCell(res.getRefs().get(0).getLabel());
+ // r.getCells().add(res);
+ return res ;
+ }
+ @SuppressWarnings("rawtypes")
+ public GuiTableCellReferences addCellRefs(EList l, String def) {
+ if (l.size() == 0) {
+ addCell(def);
+ return null;
+ }
+ StringBuffer buf = new StringBuffer();
+ GuiTableCellReferences res = f.createGuiTableCellReferences();
+ for (Object o : l) {
+ GuiTableCellReference ref = addCellRef(res,(EObject) o,def);
+ buf.append(ref.getLabel());
+ buf.append(" ");
+ }
+ // TODO removed when GUI is updated
+ addCell(buf.toString());
+ // r.getCells().add(res);
+ return res ;
+ }
+
+ private GuiTableCellReference addCellRef(GuiTableCellReferences refs, EObject o, String def) {
+ GuiTableCellReference ref = f.createGuiTableCellReference();
+ ref.setLabel(def);
+ if (o == null) return ref;
+ EStructuralFeature ff = o.eClass().getEStructuralFeature("name");
+ if (ff instanceof EAttribute) {
+ EAttribute attr = (EAttribute) ff;
+ ref.setLabel(o.eGet(attr).toString());
+ }
+ refs.getRefs().add(ref);
+ return ref;
+ }
+ public void addCellDate(long time) {
+ // TODO needed when using strings for dates.
+ addCell(String.format("%1$tm/%1$td %1$tH:%1$tM:%1$tS", new Date(time)));
+ }
+}
diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/gui/tools/GuiTimeseriesUtil.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/gui/tools/GuiTimeseriesUtil.java new file mode 100644 index 0000000..11efd8d --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/gui/tools/GuiTimeseriesUtil.java @@ -0,0 +1,26 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.gui.tools;
+
+public class GuiTimeseriesUtil {
+
+}
diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/gui/tools/GuiTreeUtil.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/gui/tools/GuiTreeUtil.java new file mode 100644 index 0000000..4f568b1 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/gui/tools/GuiTreeUtil.java @@ -0,0 +1,248 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.gui.tools; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.ConcurrentModificationException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; + +import org.apache.log4j.Logger; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; + +import org.openecomp.ncomp.sirius.manager.ManagementServer; +import org.openecomp.ncomp.gwt.siriusportal.model.*; +import org.openecomp.ncomp.sirius.manager.tableTemplate.AbstractTableTemplate; + +public class GuiTreeUtil { + public static final Logger logger = Logger.getLogger(GuiTreeUtil.class); + static ModelFactory f = ModelFactory.eINSTANCE; + GuiTree tree; + HashMap<EObject, GuiTreeNode> ecore2node = new HashMap<EObject, GuiTreeNode>(); + private ManagementServer server; + + @SuppressWarnings("rawtypes") + public GuiTreeUtil (ManagementServer server, int levels, Map options) { + this.server = server; + tree = f.createGuiTree(); + tree.getSections().addAll(ecore2node(server.getObject(),levels,options).getChildren()); + } + @SuppressWarnings("rawtypes") + public GuiTreeUtil (ManagementServer server, EObject o, int levels, Map options) { + this.server = server; + tree = f.createGuiTree(); + tree.getSections().addAll(ecore2node(o,levels,options).getChildren()); + } + + @SuppressWarnings("rawtypes") + void addEcore(String path, EObject ecore, int levels, Map options) { + EObject s = find(tree, path,false); + if (s == null) { + logger.warn("Unable to find " + path + " " + tree); + return; + } + GuiTreeNode n = (GuiTreeNode) s; + addEcore(n,ecore,levels,options); + } + @SuppressWarnings("rawtypes") + void addEcore(GuiTreeNode n, EObject ecore, int levels, Map options) { + n.getChildren().addAll(ecore2node(ecore,levels,options).getChildren()); + } + @SuppressWarnings("rawtypes") + void addEList(GuiTreeNode n, EList<EObject> l, int levels, Map options) { + for (EObject ecore: l) { + n.getChildren().add(ecore2node(ecore,levels,options)); + } + } + public GuiTreeNode addSection(String name, GuiView view) { + GuiTreeNode n1 = f.createGuiTreeNode(); + tree.getSections().add(n1); + n1.setNodeName(name); + n1.setView(view); + return n1; + } + public GuiTreeNode addNode(String path, String name, GuiView view) { + EObject s = find(tree, path,false); + if (s == null) { + logger.warn("Unable to find " + path + " " + tree); + return null; + } + GuiTreeNode n = (GuiTreeNode) s; + GuiTreeNode n1 = f.createGuiTreeNode(); + n.getChildren().add(n1); + n1.setNodeName(name); + n1.setView(view); + return n1; + } + private EObject find(EObject o, String path, boolean create) { + return find(o,path.split("/"),1,create); + } + + private EObject find(EObject o, String[] path, int i, boolean create) { + EList<GuiTreeNode> l = null; + if (i == path.length) return o; + String name = path[i]; + if (o instanceof GuiTree) { + GuiTree t = (GuiTree) o; + l = t.getSections(); + } + if (o instanceof GuiTreeNode) { + GuiTreeNode n = (GuiTreeNode) o; + l = n.getChildren(); + } + for (GuiTreeNode n : l) { + if (name.equals(n.getNodeName())) + return find(n,path,i+1,create); + } + if (create) { + GuiTreeNode n1 = f.createGuiTreeNode(); + if (o instanceof GuiTree) { + GuiTree n = (GuiTree) o; + n.getSections().add(n1); + n1.setNodeName(name); + n1.setView(GuiView.NONE); + } + if (o instanceof GuiTreeNode) { + GuiTreeNode n = (GuiTreeNode) o; + n.getChildren().add(n1); + n1.setNodeName(name); + n1.setView(GuiView.NONE); + } + return find(n1,path,i+1,create); + } + return null; + } + + @SuppressWarnings("rawtypes") + private GuiTreeNode ecore2node(EObject ecore, int levels, Map options) { + if (options == null) options = new HashMap(); + GuiTreeNode n = f.createGuiTreeNode(); + if (ecore2node.get(ecore) == null) { + ecore2node.put(ecore, n); + } + EAttribute attr = (EAttribute) ecore.eClass().getEStructuralFeature("name"); + if (attr != null) { + n.setNodeName((String) ecore.eGet(attr)); + } + if (n.getNodeName() == null) { + n.setNodeName("NONAME"); + } + n.setView(GuiView.OBJECT); + for (EReference ref : ecore.eClass().getEAllContainments()) { + Map options1 = newOptions(options,ref.getName()); + int levels1 = newLevels(options1,levels); + if (levels1 == 0) continue; + if (ref.isMany() && ! ManagementServer.refIsNamed(ref)) { + // require NamedEntity + + } + GuiTreeNode n1 = f.createGuiTreeNode(); + n1.setNodeName(ref.getName()); + n.getChildren().add(n1); + if (ref.isMany()) { + @SuppressWarnings("unchecked") + EList<EObject> l = (EList<EObject>) ecore.eGet(ref); + // Try 3 times to get list. + boolean done = false; + for (int i = 0; i < 3 ; i ++) { + try { + List<GuiTreeNode> l2 = new ArrayList<GuiTreeNode>(); + for (EObject o : l) { + l2.add(ecore2node(o,levels1,options1)); + } + n1.getChildren().addAll(l2); + break; + } catch (ConcurrentModificationException e) { + continue; + } + } + if (! done ) { + logger.error("unable to add list: " + ManagementServer.object2ref(ecore) + "@" + ref.getName()); + } + } else { + EObject o = (EObject) ecore.eGet(ref); + if (o != null) { + GuiTreeNode nn = ecore2node(o,levels1,options1); + n1.setView(GuiView.OBJECT); + n1.getChildren().addAll(nn.getChildren()); + } + } + } + return n; + } + + @SuppressWarnings("rawtypes") + private static int newLevels(Map options1, int levels) { + return options1.containsKey("LEVELS") ? (Integer) options1.get("LEVELS") : levels - 1; + } + + @SuppressWarnings("rawtypes") + private static Map newOptions(Map options, String name) { + Object o = options.get(name); + if (! (o instanceof Map)) return new HashMap(); + return (Map) o; + } + + public void addTables(EList<AbstractTableTemplate> templates) { + for (AbstractTableTemplate t: templates) { + for (EObject o : server.findAll(t.getTreePath())) { + String treePath = ManagementServer.expandPath(o,t.getTablePath(),"$"); + int i = treePath.lastIndexOf("/"); + String prefix = treePath.substring(0,i); + String name = treePath.substring(i+1); + System.err.println("Adding table: " + prefix + " " + name); + if (prefix.equals("/")) { + logger.error("cannot have table as a section"); + continue; + } + else { + find(tree,prefix,true); + addNode(prefix, name, GuiView.TABLE); + } + } + } + } + + + public void printTree() { + for (GuiTreeNode n : tree.getSections()) { + printTreeNode(n, ""); + } + } + + private void printTreeNode(GuiTreeNode t, String indent) { + System.out.println(indent + t.getNodeName() + ":" + t.getView()); + for (GuiTreeNode n : t.getChildren()) { + printTreeNode(n, " " + indent); + } + } + public GuiTree getTree() { + return tree; + } +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/AbstractClient.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/AbstractClient.java new file mode 100644 index 0000000..a61c02c --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/AbstractClient.java @@ -0,0 +1,199 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager; + +import java.util.HashMap; +import java.util.Properties; + +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EOperation; +import org.json.JSONArray; +import org.json.JSONObject; + +import org.openecomp.ncomp.utils.emf.EUtils; + +public abstract class AbstractClient { + public static final Logger logger = Logger.getLogger(AbstractClient.class); + abstract public byte[] httpBinaryTransaction(String path, String method, HashMap<String, String> headers, JSONObject body, Long timeout); + + public Properties props; + public String language; + public String namespace; + protected int defaultTimeout = 60000; + private static HashMap<EObject, AbstractClient> map1 = new HashMap<EObject, AbstractClient>(); + private static HashMap<EObject, String> map2 = new HashMap<EObject, String>(); + + public void add(String uri, EObject o) { + map1.put(o, this); + map2.put(o, uri); + } + + static AbstractClient findClient(EObject o) { + return map1.get(o); + } + + public JSONObject operationJson(EObject o, String name, Long timeout, JSONObject json) { + return operationPath2(map2.get(o), name, timeout, json); + } + + public JSONObject operationPath2(String path, String name, Long timeout, JSONObject json) { + HashMap<String, String> headers = new HashMap<String, String>(); + headers.put("action", name); + logger.debug("operation: " + name + "\n" + json.toString(2)); + return httpJsonTransaction(path, "PUT", headers, json, timeout); + } + public JSONObject operationOdl(String path, Long timeout, JSONObject json) { + JSONObject json1 = new JSONObject(); + json1.put("input", json); + logger.debug("ODL operation: " + path + "\n" + json1.toString(2)); + return httpJsonTransaction(path, "POST", null, json1, timeout); + } + + public Object operation2(String path, EObject o, String opName, Long timeout, Object[] params) { + EOperation op = EUtils.name2operation(o.eClass(), opName); + if (op == null) + throw new RuntimeException("no such operation: " + opName + " on " + o); + JSONObject res = operationPath2(path, opName, timeout, ManagementServer.params2json(op, params)); + return ManagementServer.json2response(op, res); + } + + public JSONObject operation(String resourcePath, String opName, Long timeout, JSONObject json) { + return operationPath2(resourcePath, opName, timeout, json); + } + + public Object operation(String path, EObject o, String opName, Long timeout, Object... params) { + return operation2(path, o, opName, timeout, params); + } + + public Object operation(EObject o, String opName, Long timeout, Object... params) { + return operation2(map2.get(o), o, opName, timeout, params); + } + + public Object operationPath(String resourcePath, EClass c, String opName, Long timeout, Object... params) { + EOperation op = EUtils.name2operation(c, opName); + if (op == null) { + throw new RuntimeException("Unknown operation " + opName + " on Eclass " + c.getName()); + } + JSONObject res; + JSONObject json1 = ManagementServer.params2json(op, params); + if (language != null && language.equals("restconf")) { + res = operationOdl("/restconf/operations/" + namespace + ":" + opName,timeout,json1); + } + else { + res = operationPath2(resourcePath, op.getName(), timeout, json1 ); + } + return ManagementServer.json2response(op, res); + } + + // abstract public void sendToDataRouter(String feedname, String fileId, + // JSONObject metadata, InputStream is); + + // public void sendToDataRouter(String feedname, String fileId, JSONObject + // metadata, byte[] bytes) { + // ByteArrayInputStream in = new ByteArrayInputStream(bytes); + // sendToDataRouter(feedname, fileId, metadata, in); + // } + + public void create(String resourcePath, String json) { + create(resourcePath, new JSONObject(json)); + } + + public void create(String resourcePath, JSONObject json) { + httpJsonTransaction(resourcePath, "POST", null, json, null); + } + + public void update(String resourcePath, JSONObject json) { + httpJsonTransaction(resourcePath, "PUT", null, json, null); + } + + public void delete(String resourcePath) { + httpJsonTransaction(resourcePath, "DELETE", null, new JSONObject(), null); + } + + public JSONObject method(String resourcePath, String method, JSONObject json) { + return httpJsonTransaction(resourcePath, method, null, json, null); + } + + public byte[] methodAsBinary(String resourcePath, String method, JSONObject json) { + return httpBinaryTransaction(resourcePath, method, null, json, null); + } + + public String methodAsString(String resourcePath, String method, JSONObject json) { + return httpStringTransaction(resourcePath, method, null, json, null); + } + + public JSONObject list(String resourcePath) { + if (language != null && language.equals("rest")) { + return httpJsonTransaction(resourcePath, "GET", null, new JSONObject(), null); + } else { + return list(resourcePath, 1); + } + } + + public JSONObject listAll(String resourcePath) { + return httpJsonTransaction(resourcePath + "?match=regexp", "GET", null, new JSONObject(), null); + } + + public JSONObject listReferences(String resourcePath, boolean recursive) { + return httpJsonTransaction(resourcePath + "?references=" + recursive, "GET", null, new JSONObject(), null); + } + + public JSONObject list(String resourcePath, int levels) { + return httpJsonTransaction(resourcePath + "?levels=" + levels, "GET", null, new JSONObject(), null); + } + + public JSONObject httpJsonTransaction(String path, String method, HashMap<String, String> headers, JSONObject body) { + return httpJsonTransaction(path, method, headers, body,null); + } + + public JSONObject httpJsonTransaction(String path, String method, HashMap<String, String> headers, JSONObject body, Long timeout) { + String s = httpStringTransaction(path, method, headers, body, timeout); + if (s == null) return null; + if (s.startsWith("[")) { + JSONArray a = new JSONArray(s); + JSONObject json = new JSONObject(); + json.put("$list", a); + return json; + } else { + JSONObject json = new JSONObject(s); + return json; + } + } + + public String httpStringTransaction(String path, String method, HashMap<String, String> headers, JSONObject body, Long timeout) { + byte[] b = httpBinaryTransaction(path, method, headers, body, timeout); + if (b == null) return null; + else return new String(b); + } + + public int getDefaultTimeout () { + return defaultTimeout; + } + + public void setDefaultTimeout (int timeout) { + defaultTimeout = timeout; + } + + abstract public String getRemote(); +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/BasicAdaptorProvider.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/BasicAdaptorProvider.java new file mode 100644 index 0000000..8a2a139 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/BasicAdaptorProvider.java @@ -0,0 +1,40 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager; + +// This is a base class providing the basic (essentially, no) functionality needed +// in an XxxProvider class + +public class BasicAdaptorProvider { + protected ISiriusServer controller; + + public BasicAdaptorProvider (ISiriusServer controller, Object o) { + this.controller = controller; + } + + public void start() { + } + + public static void ecoreSetup() { + } + +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/BasicGuiClientApiProvider.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/BasicGuiClientApiProvider.java new file mode 100644 index 0000000..3a01864 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/BasicGuiClientApiProvider.java @@ -0,0 +1,76 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager; + +import org.openecomp.ncomp.gwt.siriusportal.model.GuiClientApi; +import org.openecomp.ncomp.gwt.siriusportal.model.GuiObject; +import org.openecomp.ncomp.sirius.gui.tools.GuiModelUtils; +import org.openecomp.ncomp.sirius.gui.tools.GuiTreeUtil; +import org.openecomp.ncomp.sirius.manager.server.AbstractManagementServer; + +public class BasicGuiClientApiProvider extends BasicAdaptorProvider { + + @SuppressWarnings("unused") + private GuiClientApi o; + + public BasicGuiClientApiProvider(ISiriusServer controller, GuiClientApi o) { + super(controller, o); + this.o = o; + } + public org.openecomp.ncomp.gwt.siriusportal.model.GuiTree getTree() { + + GuiTreeUtil tree = new GuiTreeUtil(controller.getServer(), 100, null); + AbstractManagementServer c = (AbstractManagementServer) controller.getServer().getObject(); + if (c.getConfiguration() != null) + tree.addTables(c.getConfiguration().getTableTemplates()); + return tree.getTree(); + } + + public org.openecomp.ncomp.gwt.siriusportal.model.GuiObject getObject(java.lang.String path) { + + Subject subject = ManagementServer.find(controller.getServer().getObject(), path); + if (subject.o == null) { + throw new RuntimeException("unable to find: " + path); + } + GuiObject o = GuiModelUtils.ecore2GuiObject(subject.o, 2, null); + // oPrint(o); + return o; + } + + public org.openecomp.ncomp.gwt.siriusportal.model.GuiTimeSerie getTimeSerie(java.lang.String path, java.lang.String start, java.lang.String end, java.lang.String duration) { + return GuiModelUtils.getTimeSerie(controller.getServer(), path, start, end, duration); + } + + public org.openecomp.ncomp.gwt.siriusportal.model.GuiTable getTable(java.lang.String path, java.lang.String start, java.lang.String end) { + return GuiModelUtils.getTable(controller.getServer(), path, start, end); + } + + public org.openecomp.ncomp.gwt.siriusportal.model.GuiHtml getHtml(java.lang.String path, java.lang.String start, java.lang.String end) { + throw new UnsupportedOperationException(); + } + + public org.openecomp.ncomp.sirius.manager.graph.GuiGraph getGraph(java.lang.String path, java.lang.String start, java.lang.String end) { + throw new UnsupportedOperationException(); + } + + +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/BasicManagementServerProvider.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/BasicManagementServerProvider.java new file mode 100644 index 0000000..dd46628 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/BasicManagementServerProvider.java @@ -0,0 +1,130 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager; + +import java.util.Date; +import java.util.concurrent.atomic.AtomicLong; + +import org.apache.log4j.Logger; +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.EList; +import org.json.JSONObject; + +import org.openecomp.ncomp.core.logs.LogMessage; +import org.openecomp.ncomp.core.metrics.Metric; +import org.openecomp.ncomp.sirius.function.FunctionUtils; +import org.openecomp.ncomp.sirius.manager.properties.AbstractProperty; +import org.openecomp.ncomp.sirius.manager.server.AbstractManagementServer; +import org.openecomp.ncomp.sirius.manager.server.LoggerInfo; +import org.openecomp.ncomp.sirius.manager.server.ManagementInfo; +import org.openecomp.ncomp.sirius.manager.server.ServerFactory; + +// This is a base class providing the AbstractManagementServer functionality needed +// in an XxxProvider class + +public class BasicManagementServerProvider extends BasicAdaptorProvider { + private static final Logger logger = Logger.getLogger(BasicManagementServerProvider.class); + private AbstractManagementServer a; + + public BasicManagementServerProvider (ISiriusServer controller, AbstractManagementServer a) { + super(controller, a); + this.a = a; + } + + public void logs(JSONObject cx, EList<LogMessage> logs) { + uploadInfo(null, createManagementInfoList(cx, null, logs, null)); + } + + public void properties(JSONObject cx, EList<AbstractProperty> l) { + uploadInfo(null, createManagementInfoList(cx, null, null, l)); + } + + public void metrics(JSONObject cx, EList<Metric> metrics) { + uploadInfo(null, createManagementInfoList(cx, metrics, null, null)); + } + + AtomicLong numUploads = new AtomicLong(); + public void uploadInfo(JSONObject cx, EList<ManagementInfo> info) { + Date d = new Date(); + numUploads.incrementAndGet(); + if (cx == null) { + for (ManagementInfo i : info) { + if (i.getLogs().size() > 0) { + controller.getServer().logs.updateLogs(a,i.getLogs(),a.getConfiguration().getRules(),logger); + } + if (i.getMetrics().size() > 0) { + controller.getServer().metrics.updateMetrics(a,i.getMetrics()); + } + if (i.getProps().size() > 0) { + controller.getServer().properties.updatePropertries(a,i.getProps()); + } + } + } + logger.info("uploadInfo done: " + (new Date().getTime()-d.getTime())/1000 + " numCurrentUploads= " + numUploads.decrementAndGet()); + } + + private static EList<ManagementInfo> createManagementInfoList(JSONObject context, EList<Metric> metrics, EList<LogMessage> logs, EList<AbstractProperty> properties) { + ManagementInfo m = ServerFactory.eINSTANCE.createManagementInfo(); + EList<ManagementInfo> l = new BasicEList<ManagementInfo>(); + l.add(m); + if (metrics != null) m.getMetrics().addAll(metrics); + if (logs != null) m.getLogs().addAll(logs); + if (properties != null) m.getProps().addAll(properties); + m.setIp(context.getString("remoteIp")); + logger.info("received data from: " + m.getIp() + " #m=" + m.getMetrics().size() + " #l=" + m.getLogs().size() + " #p=" + m.getProps().size()); + return l; + } + + public EList<org.openecomp.ncomp.core.metrics.DoubleMetric> getValues(org.json.JSONObject cx, java.lang.String path, java.lang.Long start, java.lang.Long end, org.openecomp.ncomp.core.metrics.MetricValueOption option, boolean relativeInterval) { + return controller.getServer().metrics.getValues(path, start, end, option, relativeInterval); + } + + public EList<org.openecomp.ncomp.core.metrics.DoubleMetric> getValuesAll(org.json.JSONObject cx, java.lang.String path, EList<java.lang.String> metrics, java.lang.Long start, java.lang.Long end, org.openecomp.ncomp.core.metrics.MetricValueOption option, boolean relativeInterval) { + return controller.getServer().metrics.getValuesAll(path, metrics, start, end, option, relativeInterval); + } + + public EList<org.openecomp.ncomp.core.logs.LogMessage> getMessages(org.json.JSONObject cx, java.lang.String path, java.lang.Long start, java.lang.Long end) { + return controller.getServer().logs.getMessages(path, new Date(start), new Date(end)); + } + + public org.openecomp.ncomp.sirius.manager.server.LoggerInfo getRequestLogger(java.lang.String userName, java.lang.String action, java.lang.String resourcePath, org.json.JSONObject context) { + LoggerInfo info = ServerFactory.eINSTANCE.createLoggerInfo(); + info.setName(action); + return info; + } + + public EList<org.openecomp.ncomp.core.function.ValuePair> evaluate(java.lang.String path, org.openecomp.ncomp.core.function.Function function) { + return FunctionUtils.evaluate(controller.getServer().getObject(), path, function); + } + + public void update(java.lang.String path, org.openecomp.ncomp.core.function.Function function) { + // TODO IMPLEMENT + throw new UnsupportedOperationException(); + } + + public static void ecoreSetup() { + // TODO Auto-generated method stub + + } + + +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/DroolsEventReporter.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/DroolsEventReporter.java new file mode 100644 index 0000000..5a2440e --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/DroolsEventReporter.java @@ -0,0 +1,56 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager; + +import org.openecomp.ncomp.component.DroolsObjectChange; +import org.openecomp.ncomp.sirius.manager.drools.DroolsEventListener; + +public class DroolsEventReporter implements DroolsEventListener { + private final ManagementServer server; + private final String name; + + public DroolsEventReporter (ManagementServer server, String name) { + this.server = server; + this.name = name; + } + + @Override + public void recordPolicyFire(String ruleName) { + server.recordPolicyFire(name, ruleName); + } + + @Override + public void recordPolicyObjectInserted(Object o) { + server.recordPolicyObjectChange(name, o, DroolsObjectChange.INSERTED); + } + + @Override + public void recordPolicyObjectDeleted(Object o) { + server.recordPolicyObjectChange(name, o, DroolsObjectChange.DELETED); + } + + @Override + public void recordPolicyObjectUpdated(Object o) { + server.recordPolicyObjectChange(name, o, DroolsObjectChange.UPDATED); + } + +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/GenericHttpClient.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/GenericHttpClient.java new file mode 100644 index 0000000..d17f5d9 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/GenericHttpClient.java @@ -0,0 +1,31 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager; + + +public class GenericHttpClient extends JavaHttpClient { + + public GenericHttpClient(String fileName, String endpoint) { + super(fileName, endpoint); + } + +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/HighAvailabilityClient.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/HighAvailabilityClient.java new file mode 100644 index 0000000..f3d96c2 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/HighAvailabilityClient.java @@ -0,0 +1,102 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.json.JSONObject;
+
+import org.openecomp.ncomp.utils.StringUtil;
+
+public class HighAvailabilityClient extends AbstractClient {
+ public static final Logger logger = Logger.getLogger(HighAvailabilityClient.class);
+ private Jetty8Client current;
+ private List<Jetty8Client> clients = new ArrayList<Jetty8Client>();
+ public AbstractClient all = new AbstractClient() {
+ @Override
+ public byte[] httpBinaryTransaction(String path, String method, HashMap<String, String> headers, JSONObject body, Long timeout) {
+ return httpBinaryTransactionAll(path, method, headers, body, timeout);
+ }
+
+ @Override
+ public String getRemote() {
+ ArrayList<String> l = new ArrayList<String>();
+ for (AbstractClient c : clients) {
+ l.add(c.getRemote());
+ }
+ return StringUtil.join(l, ",");
+ }
+
+ };
+ public HighAvailabilityClient(String fileName, String endpoint1, String endpoint2) {
+ clients.add(new Jetty8Client(fileName, endpoint1));
+ clients.add(new Jetty8Client(fileName, endpoint2));
+ current = clients.get(0);
+ props = current.props;
+ language = current.language;
+ namespace = current.namespace;
+ }
+
+ protected byte[] httpBinaryTransactionAll(String path, String method, HashMap<String, String> headers, JSONObject body, Long timeout) {
+ byte[] res = null;
+ for (Jetty8Client c : clients) {
+ try {
+ res = c.httpBinaryTransaction(path, method, headers, body, timeout);
+ }
+ catch (Exception e) {
+ logger.warn("httpBinaryTransaction failed for: " + path + " " + method + " " + e);
+ }
+ }
+ return res;
+ }
+
+ @Override
+ public byte[] httpBinaryTransaction(String path, String method, HashMap<String, String> headers, JSONObject body, Long timeout) {
+ try {
+ return current.httpBinaryTransaction(path, method, headers, body, timeout);
+ }
+ catch (Jetty8ClientException e) {
+ current = current == clients.get(0) ? clients.get(1) : clients.get(0);
+ logger.warn("switching active client: " + current.getBaseAddress() );
+ System.err.println("switching active client: " + current.getBaseAddress() );
+ }
+ return current.httpBinaryTransaction(path, method, headers, body, timeout);
+ }
+
+ public boolean hasBase() {
+ if (clients.get(0).getBaseAddress() == null) return false;
+ if (clients.get(1).getBaseAddress() == null) return false;
+ return true;
+ }
+
+ @Override
+ public String getRemote() {
+ ArrayList<String> l = new ArrayList<String>();
+ for (AbstractClient c : clients) {
+ l.add(c.getRemote());
+ }
+ return StringUtil.join(l, ",");
+ }
+}
diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/IPolicyEngine.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/IPolicyEngine.java new file mode 100644 index 0000000..b2c3f75 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/IPolicyEngine.java @@ -0,0 +1,26 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager; + +public interface IPolicyEngine { + public boolean permit(String subject, String action, String resourcePath); +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/IRequestHandler.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/IRequestHandler.java new file mode 100644 index 0000000..f1d8020 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/IRequestHandler.java @@ -0,0 +1,31 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager; + +import java.io.InputStream; + +import org.json.JSONObject; + +public interface IRequestHandler { + Object handleJson(String userName , String action, String resourcePath, JSONObject json, JSONObject context); + Object handleBinary(String userName , String action, String resourcePath, InputStream in); +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ISiriusPlugin.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ISiriusPlugin.java new file mode 100644 index 0000000..2117a07 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ISiriusPlugin.java @@ -0,0 +1,26 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager; + +public interface ISiriusPlugin { + void start(); +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ISiriusServer.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ISiriusServer.java new file mode 100644 index 0000000..7bbb8cb --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ISiriusServer.java @@ -0,0 +1,27 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager; + +public interface ISiriusServer { + ManagementServer getServer(); +} +
\ No newline at end of file diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ISwaggerHandler.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ISwaggerHandler.java new file mode 100644 index 0000000..d253e25 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ISwaggerHandler.java @@ -0,0 +1,26 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager; + +public interface ISwaggerHandler { + void updateSwagger(String path, SwaggerUtils swagger); +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/JavaHttpClient.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/JavaHttpClient.java new file mode 100644 index 0000000..88deb35 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/JavaHttpClient.java @@ -0,0 +1,199 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager; + +import java.io.*; +import java.util.*; +import java.net.*; + +import org.apache.log4j.Logger; +import org.json.JSONObject; +import org.apache.commons.codec.binary.Base64; + +import org.openecomp.ncomp.utils.CryptoUtils; +import org.openecomp.ncomp.utils.PropertyUtil; +import org.openecomp.ncomp.webservice.utils.FileUtils; + +public class JavaHttpClient extends AbstractClient { + public static final Logger logger = Logger.getLogger(JavaHttpClient.class); + String authorization; + String baseAddress; + private boolean debug = false; + + public JavaHttpClient(String fileName, String endpoint) { + try { + props = PropertyUtil.getPropertiesFromClasspath(fileName); + setBaseAddress(props.getProperty(endpoint + ".endpoint")); + if (getBaseAddress() == null) { + logger.error("unable to determine baseAddress for endpoint: " + endpoint + " in " + fileName); + throw new RuntimeException("unable to determine baseAddress for endpoint: " + endpoint + " in " + + fileName); + } + String user = props.getProperty(endpoint + ".user"); + String password = decryptPassword(props.getProperty(endpoint + ".password")); + debug = Boolean.parseBoolean(props.getProperty(endpoint + ".debug", "false")); + if (props.containsKey(endpoint + ".timeout")) { + setDefaultTimeout(Integer.parseInt(props.getProperty(endpoint + ".timeout"))); + } + authorization = "Basic " + Base64.encodeBase64String((user + ":" + password).getBytes()); + authorization = authorization.trim(); + } catch (Exception e) { + logger.error("creating client failed: " + e.toString()); + } + } + + public static String decryptPassword(String s) { + if (s == null) return s; + if (s.startsWith("rsa:")) { + s = CryptoUtils.decryptPrivate(CryptoUtils.getKey("config/server.private"), s.substring(4)); + } + return s; + } + + + public byte[] httpBinaryTransaction(String path, String method, HashMap<String, String> headers, JSONObject body, + Long timeout) { + byte[] rawbody = null; + if ("DELETE".equals(method) || "GET".equals(method)) { + body = null; + } + if (body != null) { + rawbody = body.toString(2).getBytes(); + if (rawbody.length == 0) { + rawbody = null; + } + } + String url = getBaseAddress() + path; + int tout = defaultTimeout; + if (timeout != null) { + // units? seconds or millis? + tout = (int) timeout.longValue(); + } + HttpURLConnection uc = null; + InputStream is = null; + try { + URL u = new URL(url); + uc = (HttpURLConnection) u.openConnection(); + uc.setConnectTimeout(tout); + uc.setReadTimeout(tout); + if (headers == null) + headers = new HashMap<String, String>(); + headers.put("Content-type", "application/json"); + headers.put("Authorization", authorization); + for (String n : headers.keySet()) { + uc.setRequestProperty(n, headers.get(n)); + if (debug) { + System.err.println("HTTP REQUEST header: " + n + " " + headers.get(n)); + } + } + uc.setRequestMethod(method); + if (debug) + System.err.println("HTTP REQUEST url: " + method + " " + url); + if (rawbody != null && rawbody.length > 0) { + uc.setRequestProperty("Content-Length", Integer.toString(rawbody.length)); + uc.setFixedLengthStreamingMode(rawbody.length); + uc.setDoOutput(true); + OutputStream os = uc.getOutputStream(); + os.write(rawbody); + os.close(); + if (debug) + System.err.println("HTTP REQUEST boby: " + body); + } + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + int rc = uc.getResponseCode(); + if (rc < 200 || rc >= 300) { + is = uc.getErrorStream(); + if (is != null) + FileUtils.copyStream(is, baos); + if (baos.size() > 0 && debug) { + System.err.println("HTTP ERROR: " + url + " " + baos); + } + throw new Jetty8ClientException("HTTP Request Failed: URL: " + url + " code:" + rc + " msg:" + + uc.getResponseMessage() + " " + baos); + } + is = uc.getInputStream(); + FileUtils.copyStream(is, baos); + if (baos.size() == 0) + return null; + return (baos.toByteArray()); + } catch (RuntimeException re) { +// ManagementServerUtils.printStackTrace(re); + throw re; + } catch (Exception e) { +// ManagementServerUtils.printStackTrace(e); + throw new RuntimeException("http error: " + e, e); + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException e) { + } + } + if (uc != null) { + uc.disconnect(); + } + } + } + + public String getBaseAddress() { + return baseAddress; + } + + public void setBaseAddress(String baseAddress) { + this.baseAddress = baseAddress; + } + + public void setDebug(boolean debug) { + this.debug = debug; + } + + public void httpBinaryTransaction(String path, String method, HashMap<String, String> headers, InputStream i, int j) { + // TODO Auto-generated method stub + + } + + public void httpJsonTransaction(String path, String method, HashMap<String, String> headers, InputStream i, int j) { + // TODO Auto-generated method stub + + } + + @Override + public String getRemote() { + return getBaseAddress(); + } + + public static void main(String[] args) { + String fileName = args[0]; + String endpoint = args[1]; + JavaHttpClient c = new JavaHttpClient(fileName, endpoint); + String path = args[2]; + String method = args[3]; + JSONObject body = new JSONObject(args[4]); + JSONObject headerJson = new JSONObject(args[5]); + HashMap<String, String> headers = new HashMap<String, String>(); + for (Iterator<String> i = headerJson.keys(); i.hasNext();) { + String k = i.next(); + headers.put(k, headerJson.getString(k)); + } + c.httpJsonTransaction(path, method, headers, body); + } +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/Jetty8Client.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/Jetty8Client.java new file mode 100644 index 0000000..b5eaa4f --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/Jetty8Client.java @@ -0,0 +1,32 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager; + +// Should use GenericHttpClient +@Deprecated +public class Jetty8Client extends JavaHttpClient { + + public Jetty8Client(String fileName, String endpoint) { + super(fileName, endpoint); + } + +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/Jetty8ClientException.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/Jetty8ClientException.java new file mode 100644 index 0000000..58ce165 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/Jetty8ClientException.java @@ -0,0 +1,31 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager;
+
+class Jetty8ClientException extends RuntimeException {
+ public Jetty8ClientException(String string) {
+ super(string);
+ }
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/Jetty8ClientOld.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/Jetty8ClientOld.java new file mode 100644 index 0000000..d3aae2a --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/Jetty8ClientOld.java @@ -0,0 +1,204 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager; + +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.HashMap; + +import org.apache.log4j.Logger; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.HttpExchange; +import org.eclipse.jetty.http.ssl.SslContextFactory; +import org.eclipse.jetty.io.Buffer; +import org.eclipse.jetty.io.ByteArrayBuffer; +import org.eclipse.jetty.util.B64Code; +import org.eclipse.jetty.util.StringUtil; +import org.json.JSONObject; + +import org.openecomp.ncomp.utils.CryptoUtils; +import org.openecomp.ncomp.utils.PropertyUtil; + +@SuppressWarnings("deprecation") +public class Jetty8ClientOld extends AbstractClient { + public static final Logger logger = Logger.getLogger(Jetty8ClientOld.class); + HttpClient httpClient; + String authorization; + String baseAddress; + private boolean debug = false; + + public Jetty8ClientOld(String fileName, String endpoint) { + try { + props = PropertyUtil.getPropertiesFromClasspath(fileName); + language = props.getProperty(endpoint + ".language", "somf"); + namespace = props.getProperty(endpoint + ".namespace", null); + setBaseAddress(props.getProperty(endpoint + ".endpoint")); + if (getBaseAddress() == null) { + logger.error("unable to determine baseAddress for endpoint: " + endpoint + " in " + fileName); + throw new RuntimeException("unable to determine baseAddress for endpoint: " + endpoint + " in " + fileName); + } + String user = props.getProperty(endpoint + ".user"); + String password = decryptPassword(props.getProperty(endpoint + ".password")); + debug = Boolean.parseBoolean(props.getProperty(endpoint + ".debug","false")); +// if (debug) +// System.err.println("using " + user + " "+ password + " "+ endpoint + " " + fileName + " " + getBaseAddress()); + authorization = "Basic " + B64Code.encode(user + ":" + password, StringUtil.__ISO_8859_1); + if (props.containsKey(endpoint + ".keyStore")) { + SslContextFactory sslContextFactory = new SslContextFactory(props.getProperty(endpoint + ".keyStore")); + sslContextFactory.setKeyManagerPassword(props.getProperty(endpoint + ".keyManagerPassword")); + sslContextFactory.setKeyStorePassword(props.getProperty(endpoint + ".keyStorePassword")); + // sslContextFactory.setTrustStorePath(probs.getProperty(endpoint.trustStore")); + sslContextFactory.setTrustStorePassword(props.getProperty(endpoint + ".trustStorePassword")); + httpClient = new HttpClient(sslContextFactory); + } else + httpClient = new HttpClient(); + httpClient.start(); + } catch (Exception e) { + ManagementServerUtils.printStackTrace(e); + logger.error("creating client failed: " + e.toString()); + } + } + + private String decryptPassword(String s) { + if (s.startsWith("rsa:")) { + s = CryptoUtils.decryptPrivate(CryptoUtils.getKey("config/server.private"), s.substring(4)); + } + return s; + } + + @Override + public byte[] httpBinaryTransaction(String path, String method, HashMap<String, String> headers, JSONObject body, Long timeout) { + class Exchange extends HttpExchange { + @SuppressWarnings("unused") + String version; + int code; + String message; + @SuppressWarnings("unused") + String location; + ByteArrayOutputStream content = new ByteArrayOutputStream(); + + @Override + protected void onResponseHeader(Buffer name, Buffer value) { + // System.out.println("HEADER: " + name + " " + value); + if (name.toString().equals("Location")) + location = value.toString(); + } + + @Override + protected void onResponseStatus(Buffer httpVersion, int statusCode, Buffer statusMessage) { + logger.debug("v=" + httpVersion + " code=" + statusCode + " m=" + "statusMessage"); + version = httpVersion.toString(); + code = statusCode; + message = statusMessage.toString(); + } + + @Override + protected void onResponseContent(Buffer content) { + logger.debug("onResponseContent: " + content.toString()); + byte[] b = content.asArray(); + this.content.write(b,0,b.length); + } + } + String url = getBaseAddress() + path; + Exchange exchange = new Exchange(); + exchange.setURL(url); + exchange.setMethod(method); + if (debug) + System.err.println("HTTP REQUEST: " + method + " " + url); + if (headers == null) + headers = new HashMap<String, String>(); + headers.put("Content-type", "application/json"); + headers.put("Authorization", authorization); + for (String n : headers.keySet()) { + exchange.addRequestHeader(n, headers.get(n)); + if (debug) + System.err.println("HTTP REQUEST header: " + n + " " + headers.get(n)); + } + if (body != null) { + // exchange.setRequestContentSource(new + // ByteArrayInputStream(body.toString().getBytes())); + if (debug) System.err.println("HTTP REQUEST JSON body: " + body.toString(2)); + exchange.setRequestContent(new ByteArrayBuffer(body.toString(2).getBytes())); + } + try { + if (timeout != null && timeout > 0) { + exchange.setTimeout(timeout); + } + httpClient.send(exchange); + int exchangeState = -1; + if (debug) System.err.println("HTTP REQUEST timeout: " + timeout); + exchangeState = exchange.waitForDone(); + if (logger.isDebugEnabled()) + logger.debug("Exchange done: " + exchangeState); + if (debug) System.err.println("HTTP RESPONSE STATE: " + exchangeState + " " + exchange.code); + switch (exchange.code) { + case 200: + case 204: + break; + default: + throw new Jetty8ClientException("HTTP Exchanged Failed: URL: " + url + " state:" + exchangeState + " code:" + exchange.code + + " msg:" + exchange.message); + } + if (debug) System.out.println("HTTP RESPONSE CONTENT: " + exchange.content); + if (exchange.content.size() == 0) + return null; + return exchange.content.toByteArray(); + } catch (Jetty8ClientException e) { + throw e; + } catch (Exception e) { + ManagementServerUtils.printStackTrace(e); + String body1 = body == null ? "NULL" : body.toString(2); + logger.error("http error: " + url + " body=" + body1 + " ", e); + throw new RuntimeException("http error: " + e, e); + } + } + + public String getBaseAddress() { + return baseAddress; + } + + public void setBaseAddress(String baseAddress) { + this.baseAddress = baseAddress; + } + + public void setDebug(boolean debug) { + this.debug = debug; + } + + public void httpBinaryTransaction(String path, String method, + HashMap<String, String> headers, InputStream i, int j) { + // TODO Auto-generated method stub + + } + + public void httpJsonTransaction(String path, String method, + HashMap<String, String> headers, InputStream i, int j) { + // TODO Auto-generated method stub + + } + + @Override + public String getRemote() { + return getBaseAddress(); + } + +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/Jetty8Server.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/Jetty8Server.java new file mode 100644 index 0000000..e9774ee --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/Jetty8Server.java @@ -0,0 +1,341 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager; + +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Properties; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; +import org.eclipse.jetty.http.ssl.SslContextFactory; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.AbstractHandler; +import org.eclipse.jetty.server.nio.SelectChannelConnector; +import org.eclipse.jetty.server.ssl.SslSelectChannelConnector; +import org.eclipse.jetty.util.B64Code; +import org.eclipse.jetty.util.StringUtil; +import org.json.JSONObject; + +import org.openecomp.logger.EcompLogger; +import org.openecomp.ncomp.utils.PropertyUtil; +import org.openecomp.ncomp.webservice.utils.JsonUtils; + +public class Jetty8Server { + public static final Logger logger = Logger.getLogger(Jetty8Server.class); + static final EcompLogger ecomplogger = EcompLogger.getEcompLogger(); + Server server; + private SelectChannelConnector conn1; + private int actualport; + HashMap<String, IRequestHandler> handlerMap = new HashMap<String, IRequestHandler>(); + ServerThread thread; + private Properties props; + + class Jetty8ServerHandler extends AbstractHandler { + + private HashMap<String, String> method2action = new HashMap<String, String>(); + + { + method2action.put("POST", "CREATE"); + method2action.put("PUT", "UPDATE"); + method2action.put("GET", "LIST"); + method2action.put("DELETE", "DELETE"); + } + + @Override + public void handle(String contextPath, Request jRequest, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { + if (request.getMethod().equals("OPTIONS")) { + setResponseHeaders(response); + response.setHeader("Allow", "HEAD,GET,PUT,DELETE,OPTIONS"); + response.setStatus(200); + jRequest.setHandled(true); + return; + } + String userName = checkAuth(contextPath,jRequest); + if (userName == null) { + setResponseHeaders(response); + response.setStatus(403); + jRequest.setHandled(true); + logger.info("Authorization not valid"); + return; + } + String requestId = request.getHeader("X-ECOMP-RequestID"); + if (requestId == null) { + ecomplogger.newRequestId(); + } + else { + ecomplogger.setRequestId(requestId);; + } + String action = request.getHeader("action"); + if (action == null) { + String method = request.getMethod(); + action = method2action.get(method); + } + logger.debug("new request:" + contextPath + " " + request.getMethod() + " " + action); + Object res = null; + String contextPath1 = null; + IRequestHandler handler = null; + for (String prefix : handlerMap.keySet()) { + if (contextPath.startsWith(prefix)) { + contextPath1 = contextPath.substring(prefix.length()); + handler = handlerMap.get(prefix); + } + } + if (handler == null) { + logger.warn("request with no handler: " + contextPath); + return; + } + try { + if ("application/json".equals(jRequest.getContentType()) || jRequest.getContentType() == null) { +// ByteArrayOutputStream s = new ByteArrayOutputStream(); +// FileUtils.copyStream(request.getInputStream(), s); +// System.err.println(s); +// JSONObject json = new JSONObject(new String(s.toByteArray())); + JSONObject json = JsonUtils.stream2json(request.getInputStream()); + res = handler.handleJson(userName, action, contextPath1, json, req2context(contextPath, jRequest, userName)); + } else + throw new ManagerException(HttpServletResponse.SC_BAD_REQUEST, "Cannot use content type: " + + jRequest.getContentType()); + } catch (ManagerException e) { + setResponseHeaders(response); + response.sendError(e.code, e.getMessage()); + ManagementServerUtils.printStackTrace(e); + return; + } catch (Exception e) { + ManagementServerUtils.printStackTrace(e); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage()); + return; + } + if (res != null) { + setResponseHeaders(response); + if (res instanceof JSONObject) { + JSONObject json1 = (JSONObject) res; + PrintWriter w = response.getWriter(); + w.append(json1.toString(2)); + w.close(); + response.setStatus(200); + jRequest.setHandled(true); + } else + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Unable to handle output object: " + + res.getClass().getName()); + return; + } + response.setStatus(HttpServletResponse.SC_OK); + jRequest.setHandled(true); + } + + private void setResponseHeaders(HttpServletResponse response) { + for (Object k : props.keySet()) { + if (k instanceof String) { + String s = (String) k; + if (! s.startsWith("server.header")) continue; + response.setHeader(s.substring(14), props.getProperty(s)); + } + } + } + + private JSONObject req2context(String contextPath, Request jRequest, String user) { + JSONObject c = new JSONObject(); + c.put("remoteIp", jRequest.getRemoteAddr()); + c.put("user", user); + JSONObject p = new JSONObject(); + for (Object k : jRequest.getParameterMap().keySet()) { + if (k instanceof String) { + String kk = (String) k; + p.put(kk, jRequest.getParameter(kk)); + } + } + c.put("parameters", p); + c.put("path", contextPath); + return c; + } + } + + public Jetty8Server(String propertyFileName) { + try { + props = PropertyUtil.getPropertiesFromClasspath(propertyFileName); + String portString = props.getProperty("server.port"); + if (portString == null) + return; + int port = Integer.parseInt(portString); + server = new Server(); + if (props.containsKey("server.keyStore")) { + @SuppressWarnings("deprecation") + SslContextFactory f = new SslContextFactory(props.getProperty("server.keyStore")); + f.setKeyStorePassword(props.getProperty("server.keyStorePassword")); + f.setKeyManagerPassword(props.getProperty("server.keyManagerPassword")); + f.setTrustStore(props.getProperty("server.trustStore")); + f.setTrustStorePassword(props.getProperty("server.trustStorePassword")); + logger.info("HTTPS excluded protocols: " + Arrays.asList(f.getExcludeProtocols())); + f.addExcludeProtocols("SSLv1","SSLv2","SSLv3"); + logger.info("HTTPS excluded protocols after fix: " + Arrays.asList(f.getExcludeProtocols())); + SslSelectChannelConnector c = new SslSelectChannelConnector(f); + c.setPort(port); + c.setMaxIdleTime(30000); + server.addConnector(c); + conn1 = c; + logger.info("Adding HTTPS on port: " + port); + } else { + SelectChannelConnector c = new SelectChannelConnector(); + c.setPort(port); + server.addConnector(c); + conn1 = c; + logger.info("Adding HTTP on port: " + port); + } + server.setHandler(new Jetty8ServerHandler()); + // secondary port (assume HTTP) + portString = props.getProperty("server.port2"); + if (portString != null) { + port = Integer.parseInt(portString); + SelectChannelConnector c = new SelectChannelConnector(); + c.setPort(port); + server.addConnector(c); + logger.info("Adding HTTP on secondary port: " + port); + } + } catch (Exception e) { + // TODO Auto-generated catch block + ManagementServerUtils.printStackTrace(e); + } + } + + /** + * In unit testing, we want to start on an operating system selected port number, so we configure a port number of 0, and then use this to find out the real port number + */ + public int getPort() { + return(actualport); + } + /** + * In unit testing, we want to shut down the server + */ + public void stop() { + try { + server.stop(); + } catch (Exception e) { + } + } + + public void start() { + thread = new ServerThread(); + } + + public void join() { + try { + if (server == null) { + logger.warn("Ignore Join: server is NULL"); + return; + } + server.start(); + actualport = conn1.getLocalPort(); + server.join(); + } catch (Exception e) { + // TODO Auto-generated catch block + ManagementServerUtils.printStackTrace(e); + } + } + + public static void main(String[] args) { + new Jetty8Server("server.properties"); + + } + + public void add(String prefix, IRequestHandler h) { + handlerMap.put(prefix, h); + } + + class DummyRequestHandler implements IRequestHandler { + @Override + public Object handleJson(String userName, String action, String resourcePath, JSONObject json, + JSONObject context) { + logger.debug("handleJson: user=" + userName + " action=" + action + " path=" + resourcePath + " json=" + + json); + return null; + } + + @Override + public Object handleBinary(String userName, String action, String resourcePath, InputStream in) { + logger.info("handleBinary: user=" + userName + " action=" + action + " path=" + resourcePath); + return null; + } + } + + private class ServerThread implements Runnable { + public ServerThread() { + Thread t = new Thread(this, "jetty server"); + t.setDaemon(true); + t.start(); + } + + @Override + public void run() { + try { + server.start(); + actualport = conn1.getLocalPort(); + server.join(); + } catch (Exception e) { + // TODO Auto-generated catch block + ManagementServerUtils.printStackTrace(e); + } + } + } + + private String checkAuth(String contextPath, Request r) { + if (props.containsKey("server.noauth."+ contextPath)) + return "none"; + String s = r.getHeader("Authorization"); + if (s == null) { + logger.warn("Authorization failed: No header"); + return null; + } + String a[] = s.split(" "); + if (a.length != 2) { + logger.warn("Authorization failed: Bad header"); + return null; + } + String s1 = null; + try { + s1 = B64Code.decode(a[1], StringUtil.__ISO_8859_1); + } catch (UnsupportedEncodingException e) { + } + int i = s1.indexOf(":"); + if (i == -1) { + logger.warn("Authorization failed: Bad header"); + return null; + } + String user = s1.substring(0, i); + String pw = s1.substring(i + 1); + String pw2 = props.getProperty("server.user." + user); + boolean valid = pw.equals(JavaHttpClient.decryptPassword(pw2)); + if (!valid) + logger.warn("Authorization: bad PW: " + user +"@" + r.getRemoteAddr() + " " + pw.substring(0, 2)); + return valid ? user : null; + } + +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ManagementServer.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ManagementServer.java new file mode 100644 index 0000000..cdddcf2 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ManagementServer.java @@ -0,0 +1,2528 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager; + +import static org.openecomp.ncomp.sirius.manager.ManagementServerUtils.printStackTrace; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStreamWriter; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.ConcurrentModificationException; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.TimeZone; +import java.util.concurrent.atomic.AtomicLong; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.log4j.Logger; +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EAnnotation; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EEnum; +import org.eclipse.emf.ecore.EFactory; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EOperation; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EParameter; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.util.EDataTypeEList; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import org.openecomp.entity.EcompComponent; +import org.openecomp.entity.EcompSubComponent; +import org.openecomp.entity.EcompSubComponentInstance; +import org.openecomp.ncomp.component.Api; +import org.openecomp.ncomp.component.ApiRequestStatus; +import org.openecomp.ncomp.component.ComponentClass; +import org.openecomp.ncomp.component.ComponentFactory; +import org.openecomp.ncomp.component.DroolsObjectChange; +import org.openecomp.ncomp.core.HasOperationalState; +import org.openecomp.ncomp.core.NamedEntity; +import org.openecomp.ncomp.core.OperationalState; +import org.openecomp.ncomp.core.function.Function; +import org.openecomp.ncomp.sirius.manager.drools.DroolsRuntime; +import org.openecomp.ncomp.sirius.manager.logs.LogMessageManager; +import org.openecomp.ncomp.sirius.manager.metrics.MetricManager; +import org.openecomp.ncomp.sirius.manager.properties.PropertyManager; +import org.openecomp.ncomp.sirius.manager.server.AbstractManagementServer; +import org.openecomp.ncomp.sirius.manager.server.LoggerInfo; +import org.openecomp.ncomp.utils.PropertyUtil; +import org.openecomp.ncomp.utils.SortUtil; +import org.openecomp.ncomp.utils.StringUtil; +import org.openecomp.ncomp.webservice.utils.FileUtils; +import org.openecomp.ncomp.webservice.utils.JsonUtils; + +public class ManagementServer implements IRequestHandler, ISwaggerHandler { + public static final Logger logger = Logger.getLogger(ManagementServer.class); + private static final String PERSIST = "http://openecomp.org/sirius/persistence"; + private Jetty8Client jettyClient; + private Properties props; + private String directory; + private EObject root; + private IPolicyEngine pe = new SimplePolicyEngine(); + private DroolsRuntime droolsRuntime; + + private EFactory eFactory; + private String eClassName; + private String propertyFileName; + public LogMessageManager logs; + public MetricManager metrics; + public PropertyManager properties; + public boolean isSlave = false; + + public ManagementServer(EFactory eFactory, String eClassName, String directory, String propertyFileName) { + TimeZone.setDefault(TimeZone.getTimeZone("GMT")); + this.eFactory = eFactory; + this.eClassName = eClassName; + this.directory = directory; + this.propertyFileName = propertyFileName; + try { + props = PropertyUtil.getPropertiesFromClasspath(this.propertyFileName); + EcompComponent.initialize(props.getProperty("ecomp.component", "UNKNOWN_COMPONENT")); + EcompSubComponent.initialize(props.getProperty("ecomp.subcomponent", "UNKNOWN_SUBCOMPONENT")); + logs = new LogMessageManager(this); + metrics = new MetricManager(this); + properties = new PropertyManager(this); + } catch (Exception e) { + printStackTrace(e); + System.exit(1); + } + // logger.info("Starting Management Server"); + // jettyClient = new Jetty8Client(); + } + + public ManagementServer() { + // TODO Auto-generated constructor stub + } + + static AtomicLong requestId = new AtomicLong(); + + @Override + public Object handleJson(String userName, String action, String resourcePath, JSONObject json, JSONObject context) { + logger.debug("handleJson: " + userName + " " + action + " " + resourcePath + " " + context.get("remoteIp")); + long start = new Date().getTime(); + String reqId = Long.toString(start) + ":" + requestId.incrementAndGet(); + context.put("requestId", reqId); + Logger logger2 = findRequestLogger(userName, action, resourcePath, context); + if (logger2.isInfoEnabled()) { + JSONObject r = new JSONObject(); + r.put("id", reqId); + r.put("start", start); + r.put("user", userName); + r.put("action", action); + r.put("path", resourcePath); + r.put("req", json); + r.put("context", context); + logger2.info(r.toString()); + } + if (!pe.permit(userName, action, resourcePath)) { + handleJsonReportResult(reqId, start, null, "NOT_PERMITTED", logger2); + throw new RuntimeException("Action not permitted: " + userName + " " + action + " " + resourcePath); + } + Subject subject = find(resourcePath); + if (action.equals("UPDATE")) { + if (subject == null || subject.o == null) { + throw new RuntimeException("Unable to find to update: " + resourcePath); + } + boolean useNulls = false; + if (context != null && context.has("parameters")) { + JSONObject m = (JSONObject) context.get("parameters"); + useNulls = m.has("useNulls"); + } + try { + Object res = update(userName, subject, json, useNulls); + handleJsonReportResult(reqId, start, res, "OK", logger2); + return res; + } catch (RuntimeException e) { + handleJsonReportResult(reqId, start, null, "ERROR", logger2); + printStackTrace(e); + throw e; + } + } + if (action.equals("CREATE")) { + String id = null; + if (subject != null) { + if (subject.ref == null || subject.ref.isMany()) { + handleJsonReportResult(reqId, start, null, "CREATE_ON_EXISTING_RESOURCE", logger2); + throw new RuntimeException("resource already exists: " + resourcePath); + } + } else { + int index = resourcePath.lastIndexOf("/"); + id = resourcePath.substring(index + 1, resourcePath.length()); + subject = find(resourcePath.substring(0, index)); + if (subject == null || subject.o == null) { + throw new RuntimeException("unable to find resource"); + } + if (subject.ref == null) + subject.ref = findRefByName(subject.o, id); + else + json.put("name", id); + } + Object res = create(subject, json, !json.has("$nosave")); + handleJsonReportResult(reqId, start, res, "OK", logger2); + return res; + } + if (action.equals("DELETE")) { + if (subject == null || subject.o == null) { + throw new RuntimeException("Unable to find to delete: " + resourcePath); + } + Object res = delete(subject); + handleJsonReportResult(reqId, start, res, "OK", logger2); + return res; + } + if (action.equals("LIST")) { + int levels = 1; + if (context != null && context.has("parameters")) { + JSONObject m = (JSONObject) context.get("parameters"); + if (m.has("levels")) + levels = Integer.parseInt((String) m.get("levels")); + if (m.has("match")) { + JSONObject res = new JSONObject(); + res.put("list", list2jsonArray(findAll(resourcePath))); + handleJsonReportResult(reqId, start, res, "OK", logger2); + return res; + } + if (m.has("references")) { + boolean b = m.getBoolean("references"); + JSONObject res = new JSONObject(); + if (subject == null || subject.o == null) { + throw new RuntimeException("Unable to find object: " + resourcePath); + } + res.put("list", subjectList2jsonArray(findReferences(root, subject.o, b))); + handleJsonReportResult(reqId, start, res, "OK", logger2); + return res; + } + } + if (subject == null || subject.o == null) { + throw new RuntimeException("Unable to find to list: " + resourcePath); + } + Object res = list(subject, levels); + handleJsonReportResult(reqId, start, res, "OK", logger2); + return res; + } + if (subject == null || subject.o == null) { + throw new RuntimeException("Unable to find object for operation: " + resourcePath); + } + Object res = operation(subject, action, json, context); + transformResult(subject,action,res); + handleJsonReportResult(reqId, start, res, "OK", logger2); + return res; + } + + private void transformResult(Subject subject, String action, Object res) { + String a = (subject != null && subject.o != null) ? ( subject.o.eClass().getInstanceClassName() + "@" + action ) : action; +// System.out.println("KKKKKKK:" + subject + " " + action + " " + a); +// System.out.println("KKKKKKK:" + res + " " + props.getProperty(a)); + if ((res instanceof JSONObject) && props.getProperty(a + ".replace") != null) { + JSONObject json = (JSONObject) res; + String[] aa = props.getProperty(a + ".replace").split(","); + transformJsonValues(json,aa[0],aa[1]); + } + } + + private void transformJsonValues(JSONObject json, String string1, String string2) { + for (Iterator<String> i = json.keys(); i.hasNext();) { + String key = (String) i.next(); + Object o = json.get(key); + if (o instanceof String) { + json.put(key, ((String) o).replace(string1,string2)); +// System.out.println("KKKKKKK:" + o + " " + json.get(key)); + } + if (o instanceof JSONObject) { + transformJsonValues((JSONObject) o,string1,string2); + } + if (o instanceof JSONArray) { + transformJsonValues((JSONArray) o,string1,string2); + } + } + } + + private void transformJsonValues(JSONArray a, String string1, String string2) { + for (int i = 0; i < a.length(); i++) { + Object o = a.get(i); + if (o instanceof JSONObject) { + transformJsonValues((JSONObject) o,string1,string2); + } + if (o instanceof JSONArray) { + transformJsonValues((JSONArray) o,string1,string2); + } + } + } + + private Logger findRequestLogger(String userName, String action, String resourcePath, JSONObject context) { + String logdir = getProps().getProperty("requestlog.dir", "logs"); + if (root instanceof AbstractManagementServer) { + AbstractManagementServer a = (AbstractManagementServer) root; + LoggerInfo i = a.getRequestLogger(userName, action, resourcePath, context); + return ManagementServerUtils.createLogger("requests-" + i.getName(), "INFO", "%d %5p %m%n", logdir); + } + return ManagementServerUtils.createLogger("requests-" + action, "INFO", "%d %5p %m%n", logdir); + } + + private void handleJsonReportResult(String reqId, long start, Object res, String status, Logger logger2) { + if (logger2.isInfoEnabled()) { + JSONObject r = new JSONObject(); + long duration = new Date().getTime() - start; + r.put("id", reqId); + r.put("duration", duration); + r.put("status", status); + if (res instanceof JSONObject) { + JSONObject j = (JSONObject) res; + r.put("res", j); + } + logger2.info(r.toString()); + } + } + + public void start() throws IOException { + if (directory != null) + root = load(directory); + if (root instanceof IPolicyEngine) { + pe = (IPolicyEngine) root; + } + startRecursively(root); + } + + public static void startRecursively(EObject o) { + for (EReference ref : o.eClass().getEAllContainments()) { + if (ref.isMany()) { + @SuppressWarnings("unchecked") + EList<EObject> l = (EList<EObject>) o.eGet(ref); + for (EObject o1 : l) { + startRecursively(o1); + } + } else { + EObject o1 = (EObject) o.eGet(ref); + if (o1 != null) + startRecursively(o1); + } + } + if (o instanceof ISiriusPlugin) { + ISiriusPlugin p = (ISiriusPlugin) o; + p.start(); + } + } + + public EFactory addFactory(EFactory f) { + if (f.getEPackage() == null) { + throw new RuntimeException("Null Package: " + f); + } + String s = f.getEPackage().getNsURI(); + if (!string2factory.containsKey(s)) { + string2factory.put(f.getEPackage().getNsURI(), f); + logger.info("added factory: " + s); + } + return string2factory.get(s); + } + + public void addRuntimeFactories(ISiriusServer server) { + addRuntimeFactories(server, "runtime.properties"); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void addRuntimeFactories(ISiriusServer server, String runtimepropertyfile) { + String v = null; + try { + Properties p = PropertyUtil.getPropertiesFromClasspath(runtimepropertyfile); + for (Object k : p.keySet()) { + String kk = (String) k; + v = p.getProperty(kk).trim(); + if (kk.startsWith("factory.")) { + try { + Class c = Class.forName(v); + if (v.endsWith("PackageImpl")) { + Method m = c.getMethod("init"); + EPackage p1 = (EPackage) m.invoke(null); + addFactory(p1.getEFactoryInstance()); + } else { + Constructor constructor = c.getConstructor(new Class[] { ISiriusServer.class }); + addFactory((EFactory) constructor.newInstance(server)); + } + logger.info("added runtime factory: " + v); + } catch (NoSuchMethodException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InstantiationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvocationTargetException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ClassNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + } catch (IOException e) { + logger.info("No runtime propertyFile " + runtimepropertyfile); + } + } + + private EObject load(String directory) throws IOException { + return loadObjectFromDirectory(eFactory, eClassName, directory, true); + } + + private EObject loadObjectFromDirectory(EFactory eFactory, String eClassName, String directory, boolean b) + throws IOException { + List<Ref> refs = new ArrayList<ManagementServer.Ref>(); + EObject res = loadObjectFromDirectory(eFactory, eClassName, directory, true, refs); + updateRefs(res, refs); + return res; + } + + private EObject loadObjectFromDirectory(EFactory f, String cName, String directory, boolean isRoot, List<Ref> refs) + throws IOException { + String jsonFile = directory + (isRoot ? "/ROOT.json" : ".json"); + JSONObject json; + try { + File file = new File(jsonFile); + if (file.exists()) + json = JsonUtils.file2json(jsonFile); + else + json = new JSONObject(); + } catch (JSONException e) { + // printStackTrace(e,); + throw new RuntimeException("Invalid JSON: " + jsonFile + " " + e); + } + EObject res; + try { + res = loadObjectFromJson(f, cName, directory, json, refs); + handleReference(res, json, refs); + handleTransientAttributes(res, "server"); + } catch (Exception e) { + printStackTrace(e); + throw new RuntimeException("Serialization issue: " + jsonFile, e); + } + return res; + } + + private HashMap<String, EFactory> string2factory = new HashMap<String, EFactory>(); + + private EObject loadObjectFromJson(EFactory f, String cName, String directory, JSONObject json, List<Ref> refs) + throws IOException { + f = addFactory(f); + HashSet<String> used = new HashSet<String>(); + if (json.has("$ecore")) { + used.add("$ecore"); + String pp = json.getJSONObject("$ecore").getString("ePackage"); + if (pp == null) + throw new RuntimeException("Package not found: " + json.toString(2)); + f = string2factory.get(pp); + cName = json.getJSONObject("$ecore").getString("eClass"); + if (f == null) + throw new RuntimeException("Factory not found: " + pp); + } + if (json.has("$class")) { + used.add("$class"); + String v = SomfVersionUpgrade(json.getString("$class")); + int i = v.lastIndexOf("."); + String pp = v.substring(0, i); + f = string2factory.get(pp); + cName = v.substring(i + 1); + if (f == null) { + throw new RuntimeException("Factory not found: " + pp); + } + } + if (f == null) { + throw new RuntimeException("Null Factory: " + json.toString(2)); + } + if (f.getEPackage() == null) { + throw new RuntimeException("Null Package: " + f + " " + json.toString(2)); + } + EClass c = (EClass) f.getEPackage().getEClassifier(cName); + if (c == null) { + logger.error("unable to create class: " + cName + " using factory " + f.getEPackage().getName() + " " + + json.toString(2)); + throw new RuntimeException("Unable to create class " + cName + " using factory " + + f.getEPackage().getName()); + } + EObject o = f.create(c); + // if (json.has("$class")) { + // System.err.println("creating object: " + directory + " " + f + " " + + // c); + // System.err.println(cName + " " + json); + // } + for (EAttribute attr : o.eClass().getEAllAttributes()) { + if (!json.has(attr.getName())) + continue; + if (o instanceof NamedEntity && attr.getName().equals("lastChanged") || o instanceof NamedEntity + && attr.getName().equals("created")) { + used.add(attr.getName()); + continue; + } + used.add(attr.getName()); + Object oJson = json.get(attr.getName()); + if (attr.isMany()) { + if (!(oJson instanceof JSONArray)) { + throw new RuntimeException("expect array of value: " + attr.getName()); + } + JSONArray aJson = (JSONArray) oJson; + @SuppressWarnings("unchecked") + EList<Object> l = (EList<Object>) o.eGet(attr); + for (int i = 0; i < aJson.length(); i++) { + l.add(jsonValue2attrValue(attr.getEAttributeType(), aJson.get(i))); + } + } else { + Object oo = null; + try { + if (attr.getEType().getName().endsWith("MetricAttribute")) { + // metric: use the metric APIs and need to be done after + // object is in the main tree. + } else { + oo = jsonValue2attrValue(attr.getEAttributeType(), oJson); + o.eSet(attr, oo); + } + } catch (Exception e) { + logger.error("Unable to set attr: eClass " + o.eClass().getName() + "@" + attr.getName() + " " + e); + System.err.println("Unable to set attr: eClass " + o.eClass().getName() + "@" + attr.getName() + + " " + attr.getEType().getName() + " " + e + " value=" + oJson + " class=" + + oJson.getClass() + " oo=" + oo + " class=" + (oo != null ? oo.getClass() : "")); + printStackTrace(e); + } + } + } + for (EReference ref : o.eClass().getEAllContainments()) { + if (json.has(ref.getName()) && !jsonHasVersion(json.get(ref.getName()))) { + // use JSON + used.add(ref.getName()); + Object oJson = json.get(ref.getName()); + if (ref.isMany()) { + @SuppressWarnings("unchecked") + EList<EObject> l = (EList<EObject>) o.eGet(ref); + EAttribute namingAttr = namingAttribute(ref); + if (oJson instanceof JSONObject) { + if (namingAttr != null) { + JSONObject ooJson = (JSONObject) oJson; + for (Iterator<String> i = ooJson.keys(); i.hasNext();) { + String k = i.next(); + if (k.startsWith("$")) continue; + if (ooJson.get(k) instanceof JSONArray) { + JSONArray a = (JSONArray) ooJson.get(k); + } + if (! (ooJson.get(k) instanceof JSONObject)) { + throw new RuntimeException("expect json of value: " + o.eClass().getName() + "@" + + ref.getName() + "." + k + " " + ooJson.get(k)); + } + JSONObject json2 = (JSONObject) ooJson.get(k); + json2.put(namingAttr.getName(), k); + String dir = directory + "/" + ref.getName(); + l.add(loadObjectFromJson(ref2factory(ref), ref.getEReferenceType().getName(), dir, + json2, refs)); + } + continue; + } + + } + if (!(oJson instanceof JSONArray)) { + throw new RuntimeException("expect object or array of value: " + ref.getName()); + } + JSONArray aJson = (JSONArray) oJson; + for (int i = 0; i < aJson.length(); i++) { + if (aJson.get(i) instanceof JSONObject) { + JSONObject json2 = (JSONObject) aJson.get(i); + if (namingAttr != null && ! json2.has(namingAttr.getName())) { + json2.put(namingAttr.getName(),Integer.toString(i)); + } + String dir = directory + "/" + ref.getName(); + l.add(loadObjectFromJson(ref2factory(ref), ref.getEReferenceType().getName(), dir, json2, + refs)); + } else + throw new RuntimeException("expect json of value: " + o.eClass().getName() + "@" + + ref.getName()); + } + } else { + if (oJson instanceof JSONObject) { + JSONObject json2 = (JSONObject) oJson; + String dir = directory + "/" + ref.getName(); + EObject o2 = loadObjectFromJson(ref2factory(ref), ref.getEReferenceType().getName(), dir, + json2, refs); + o.eSet(ref, o2); + } else if (oJson == null || oJson.getClass().getCanonicalName().equals("org.json.JSONObject.Null")) { + // null + } else + throw new RuntimeException("expect json of value: " + f.getEPackage().getName() + "." + cName + + " " + ref.getName() + " " + oJson.getClass().getCanonicalName()); + } + } else if (directory != null) { + // Look in Directory + if (ref.isMany()) { + @SuppressWarnings("unchecked") + EList<EObject> l = (EList<EObject>) o.eGet(ref); + File file = new File(directory + "/" + ref.getName()); + if (file.isDirectory()) { + EAttribute f1 = namingAttribute(ref); + File[] files = file.listFiles(); + if (files == null) { + logger.error("directory listing failed IO error??: " + file); + continue; + } + for (File file1 : sortFiles(directory, ref, files, json, used)) { + if (file1.getName().endsWith(".json")) { + String name = file1.getName().replace(".json", ""); + String dir2 = directory + "/" + ref.getName() + "/" + name; + EObject oo = loadObjectFromDirectory(ref2factory(ref), ref.getEType().getName(), dir2, + false, refs); + if (f1 != null) + oo.eSet(f1, name); + l.add(oo); + } + } + } + } else { + File file = new File(directory + "/" + ref.getName() + ".json"); + if (file.exists()) { + EObject oo = loadObjectFromDirectory(ref2factory(ref), ref.getEType().getName(), directory + + "/" + ref.getName(), false, refs); + o.eSet(ref, oo); + } + } + } + } + for (Iterator<String> i = json.keys(); i.hasNext();) { + String k = i.next(); + if (used.contains(k)) + continue; + Object o1 = json.get(k); + if (o1 instanceof JSONObject) { + JSONObject json1 = (JSONObject) o1; + if (json1.has("$ref")) + continue; + } + if (o1 instanceof JSONArray) { + JSONArray a1 = (JSONArray) o1; + if (a1.length() == 0) + continue; + Object o2 = a1.get(0); + if (o2 instanceof JSONObject) { + JSONObject json2 = (JSONObject) o2; + if (json2.has("$ref")) + continue; + } + } + if (k.equals("$nosave")) + continue; + logger.warn("JSON value not used: " + k + " " + f.getEPackage().getName() + "." + cName + " " + json.get(k)); + } + return o; + } + + private String SomfVersionUpgrade(String className) { + if (className.equals("org.openecomp.ncomp.sirius.manager.model.StringMetric")) + return "org.openecomp.ncomp.core.metrics.StringMetric"; + if (className.equals("org.openecomp.ncomp.sirius.manager.model.DoubleMetric")) + return "org.openecomp.ncomp.core.metrics.DoubleMetric"; + if (className.equals("org.openecomp.ncomp.sirius.manager.model.LongMetric")) + return "org.openecomp.ncomp.core.metrics.LongMetric"; + if (className.equals("org.openecomp.ncomp.sirius.manager.model.ModuleProperty")) + return "org.openecomp.ncomp.sirius.manager.properties.ModuleProperty"; + return className; + } + + private List<File> sortFiles(String dir, EReference ref, File[] files, JSONObject json, HashSet<String> used) { + // boolean debug = dir.contains("metricOptions"); + List<File> res = new ArrayList<File>(); + Arrays.sort(files); + for (File f : files) { + if (f.getName().endsWith(".json")) + res.add(f); + } + // if (debug) System.err.println("HERE: " + json.toString(2)); + if (ref.isOrdered() && json.has("$order:" + ref.getName())) { + used.add("$order:" + ref.getName()); + try { + JSONArray a = json.getJSONArray("$order:" + ref.getName()); + List<File> files1 = new ArrayList<File>(); + HashMap<String, File> m = new HashMap<String, File>(); + for (File f : res) { + m.put(f.getName(), f); + } + for (int i = 0; i < a.length(); i++) { + String n = a.getString(i) + ".json"; + if (m.containsKey(n)) { + files1.add(m.remove(n)); + // if (debug) System.err.println("HERE: added1 " + + // files1.get(files1.size()-1)); + } else { + logger.warn("files does not contain key:" + n + " in " + dir); + } + } + for (String n : SortUtil.sort(m.keySet())) { + files1.add(m.get(n)); + // if (debug) System.err.println("HERE: added2 " + + // files1.get(files1.size()-1)); + logger.warn("order does not contain key:" + n + " in " + dir); + } + return files1; + } catch (Exception e) { + ManagementServerUtils.printStackTrace(e); + return res; + } + } else { + return res; + } + } + + private HashMap<String, Properties> name2properties = new HashMap<String, Properties>(); + + private void handleTransientAttributes(EObject o, String path) { + for (EAttribute attr : o.eClass().getEAllAttributes()) { + if (!attr.isTransient()) + continue; + EAnnotation anno = attr.getEAnnotation(PERSIST); + if (anno == null) + continue; + if (attr.isMany()) { + logger.warn("property persistence for list attributes not current supported: " + attr2name(attr)); + continue; + } + String propertyFile = anno.getDetails().get("propertyFile"); + if (propertyFile == null) { + logger.warn("Missing persistence detail propertyFile: " + attr2name(attr)); + continue; + } + Properties p; + if (name2properties.get(propertyFile) == null) { + p = new Properties(); + try { + p = PropertyUtil.getPropertiesFromClasspath(propertyFile); + } catch (IOException e) { + logger.warn("Missing persistence propertyFile: " + propertyFile + " " + e); + } + name2properties.put(propertyFile, p); + } + p = name2properties.get(propertyFile); + String path1 = path + "." + attr.getName(); + String s = p.getProperty(path1); + if (s == null) { + logger.warn("unable to determine value for: " + attr2name(attr) + " path: " + path1 + " file: " + + propertyFile); + } + o.eSet(attr, stringValue2attrValue(attr.getEAttributeType(), s)); + } + for (EReference ref : o.eClass().getEAllContainments()) { + if (ref.isMany()) { + @SuppressWarnings("unchecked") + EList<EObject> l = (EList<EObject>) o.eGet(ref); + for (EObject oo : l) { + EStructuralFeature f = oo.eClass().getEStructuralFeature("name"); + if (f instanceof EAttribute) { + EAttribute attr = (EAttribute) f; + Object nn = oo.eGet(attr); + if (!(nn instanceof String)) + continue; + String path1 = path + "." + ref.getName() + "." + nn; + handleTransientAttributes(oo, path1); + } + } + } else { + String path1 = path + "." + ref.getName(); + EObject oo = (EObject) o.eGet(ref); + if (oo != null) + handleTransientAttributes(oo, path1); + } + } + } + + private String attr2name(EAttribute attr) { + StringBuffer b = new StringBuffer(); + b.append(attr.getEContainingClass().getEPackage().getName()); + b.append("::"); + b.append(attr.getEContainingClass().getName()); + b.append("::"); + b.append(attr.getName()); + return b.toString(); + } + + private String ref2name(EReference ref) { + StringBuffer b = new StringBuffer(); + b.append(ref.getEContainingClass().getEPackage().getName()); + b.append("::"); + b.append(ref.getEContainingClass().getName()); + b.append("::"); + b.append(ref.getName()); + return b.toString(); + } + + int j = 0; + public boolean saveOnCreate = true; + + private EFactory ref2factory(EReference ref) { + return ref.getEReferenceType().getEPackage().getEFactoryInstance(); + } + + private EObject loadObjectFromJson(EFactory f, String cName, JSONObject json, List<Ref> refs) { + try { + return loadObjectFromJson(f, cName, null, json, refs); + } catch (IOException e) { + printStackTrace(e); + } + return null; + } + + static int id = 0; + + public Properties getProps() { + return props; + } + + private EReference findRefByName(EObject o, String name) { + return (EReference) o.eClass().getEStructuralFeature(name); + } + + @SuppressWarnings("unused") + private EAttribute findAttrByName(EObject o, String name) { + return (EAttribute) o.eClass().getEStructuralFeature(name); + } + + public Subject find(String resourcePath) { + return find(root, resourcePath); + } + + static public Subject find(EObject o, String resourcePath) { + return find(o, resourcePath, false); + } + + static public Subject find(EObject o, String resourcePath, boolean allowPartial) { + if (resourcePath.equals("/")) + return new Subject(o); + if (resourcePath.startsWith("../..")) + return (o.eContainer() == null) ? null : find(o.eContainer(), resourcePath.substring(3), allowPartial); + if (resourcePath.startsWith("../")) + return (o.eContainer() == null) ? null : find(o.eContainer(), resourcePath.substring(2), allowPartial); + return find(o, resourcePath.split("/"), 1, allowPartial); + } + + static private Subject find(EObject o, String[] l, int i, boolean allowPartial) { + if (o == null) + return null; + if (i == l.length) + return new Subject(o); + EStructuralFeature f = o.eClass().getEStructuralFeature(l[i]); + if (f instanceof EReference) { + EReference ref = (EReference) f; + if (ref.isMany()) { + if (i + 1 == l.length) + return new Subject(o, ref); + @SuppressWarnings("unchecked") + EList<EObject> ll = (EList<EObject>) o.eGet(ref); + for (EObject oo : ll) { + String s = ecoreId(oo); + if (s != null && s.equals(l[i + 1])) + return find(oo, l, i + 2, allowPartial); + } + if (allowPartial) + return new Subject(o, ref); + } else { + EObject oo = (EObject) o.eGet(ref); + if (oo == null && allowPartial) + return new Subject(o, ref); + return find(oo, l, i + 1, allowPartial); + } + } + if (f instanceof EAttribute && i + 1 == l.length) { + return new Subject(o, (EAttribute) f); + } + if (allowPartial) + return new Subject(o); + return null; + } + + public List<EObject> findAll(String resourcePath) { + return findAll(root, resourcePath); + } + + static public List<EObject> findAll(EObject o, String resourcePath) { + List<EObject> res = new ArrayList<EObject>(); + if (resourcePath.equals("/") || resourcePath.equals("")) { + res.add(o); + } else { + findAll(o, resourcePath.split("/"), resourcePath.startsWith("/") ? 1 : 0, res); + } + return res; + } + + static private void findAll(EObject o, String[] l, int i, List<EObject> res) { + if (o == null) + return; + if (i == l.length) { + res.add(o); + return; + } + EStructuralFeature f = o.eClass().getEStructuralFeature(l[i]); + if (f instanceof EReference) { + EReference ref = (EReference) f; + if (ref.isMany()) { + if (i + 1 == l.length) + return; + @SuppressWarnings("unchecked") + EList<EObject> ll = (EList<EObject>) o.eGet(ref); + for (EObject oo : ll) { + String s = ecoreId(oo); + if (s != null && s.matches(l[i + 1])) + findAll(oo, l, i + 2, res); + } + } else { + findAll((EObject) o.eGet(ref), l, i + 1, res); + } + } + } + + public static EList<Subject> findReferences(EObject root, EObject o, boolean recursive) { + EList<Subject> res = new BasicEList<Subject>(); + if (recursive) { + for (EObject o1 : object2containedObjects(o)) { + // System.err.println(object2ref(root) + " " + object2ref(o1)); + findReferences(root, o1, res); + } + } else + findReferences(root, o, res); + return res; + } + + private static void findReferences(EObject oo, EObject o, EList<Subject> res) { + if (oo == o) + return; + // if (object2ref(oo).startsWith("/con")) + // System.err.println("XYZZZ: " + object2ref(oo) + " " + object2ref(o)); + for (EReference ref : oo.eClass().getEAllReferences()) { + if (ref.isContainment()) { + for (EObject o1 : ref2objects(oo, ref)) { + findReferences(o1, o, res); + } + } else { + for (EObject o1 : ref2objects(oo, ref)) { + if (o1 == o) { + res.add(new Subject(oo, ref)); + } + } + } + } + + } + + @SuppressWarnings("unchecked") + private static EList<EObject> ref2objects(EObject o, EReference ref) { + EList<EObject> res = new BasicEList<EObject>(); + Object x = o.eGet(ref); + if (ref.isMany()) { + // Try 3 times to create list. + boolean done = false; + for (int i = 0; i < 3; i++) { + try { + res.clear(); + res.addAll((EList<EObject>) x); + done = true; + break; + } catch (ConcurrentModificationException e) { + if (i == 2) { + logger.error("Failing to create object list: " + object2ref(o) + " @ " + ref.getName(), e); + } + continue; + } + } + if (!done) { + System.err.println("unable to create object list: " + object2ref(o) + "@" + ref.getName()); + + logger.error("unable to create object list: " + object2ref(o) + "@" + ref.getName()); + } + } else { + if (x != null) + res.add((EObject) x); + } + return res; + } + + public static EList<EObject> object2containedObjects(EObject o) { + EList<EObject> res = new BasicEList<EObject>(); + object2containedObjects(o, res); + return res; + } + + private static void object2containedObjects(EObject o, EList<EObject> res) { + res.add(o); + for (EReference ref : o.eClass().getEAllReferences()) { + if (ref.isContainment()) { + for (EObject o2 : ref2objects(o, ref)) { + object2containedObjects(o2, res); + } + } + } + } + + private Object create(Subject subject, JSONObject json, boolean save) { + EObject o = subject.o; + EReference ref = subject.ref; + if (ref == null) + throw new RuntimeException("Need ref name"); + List<Ref> refs = new ArrayList<ManagementServer.Ref>(); + EObject oo = loadObjectFromJson(ref2factory(ref), ref.getEReferenceType().getName(), json, refs); + handleReference(oo, json, refs); + updateRefs(root, refs); + if (ref.isMany()) { + @SuppressWarnings("unchecked") + EList<EObject> ll = (EList<EObject>) o.eGet(ref); + ll.add(oo); + } else { + if (o.eGet(ref) != null) + throw new RuntimeException("Cannot create: object already exists"); + o.eSet(ref, oo); + } + String path = "server" + object2ref(oo); + handleTransientAttributes(oo, path.replace("/", ".")); + setCreated(oo); + if (save) { + save(); + } else { + if (logger.isDebugEnabled()) + logger.debug("create not saved: " + object2ref(oo)); + } + if (oo instanceof ISiriusPlugin) { + ISiriusPlugin oo2 = (ISiriusPlugin) oo; + oo2.start(); + } + return null; + } + + public EObject json2ecore(EClass eClass, JSONObject json) { + return json2ecore(eClass, json, true); + } + + public EObject json2ecore(EClass eClass, JSONObject json, boolean refRelativeToRoot) { + List<Ref> refs = new ArrayList<ManagementServer.Ref>(); + EObject oo = loadObjectFromJson(eClass.getEPackage().getEFactoryInstance(), eClass.getName(), json, refs); + handleReference(oo, json, refs); + updateRefs(refRelativeToRoot ? root : oo, refs); + return oo; + } + + public EObject findAndCreate(EObject o, String path) { + Subject s = findAndCreateSubject(o, path); + if (s.ref == null) + return s.o; + return (EObject) o.eGet(s.ref); + } + + public Subject findAndCreateSubject(EObject o, String path) { + Subject s = find(o, path); + if (s != null && s.o != null) { + return s; + } + int index = path.lastIndexOf("/"); + String id = path.substring(index + 1, path.length()); + if (id.length() == 0) { + throw new RuntimeException("empty string ID: " + object2ref(o) + " " + path); + } + String path1 = path.substring(0, index); + Subject s1 = findAndCreateSubject(o, path1); + if (s1 == null || s1.o == null) { + throw new RuntimeException("unable to find resource: " + object2ref(o) + " " + path); + } + s = find(o, path); + if (s == null) { + JSONObject json = new JSONObject(); + json.put("$nosave", true); // TODO + if (s1.ref != null && s1.ref.isMany()) { + json.put("name", id); + } + if (s1.ref == null) { + s1.ref = findRefByName(s1.o, id); + } + // System.err.println("PP creating: " + object2ref(o) + " " + path); + // Thread.dumpStack(); + create(s1, json, true); + return find(o, path); + } else + return s; + } + + public Object update(String userName, Subject subject, JSONObject json, boolean useNulls) { + EObject o = subject.o; + EReference ref = subject.ref; + if (json == null) + throw new RuntimeException("Need object to update"); + if (o == null || ref != null) + throw new RuntimeException("Need object to update"); + List<Ref> refs = new ArrayList<ManagementServer.Ref>(); + EObject oo = loadObjectFromJson(o.eClass().getEPackage().getEFactoryInstance(), o.eClass().getName(), json, + refs); + handleReference(oo, json, refs); + List<EObject> deleted = new ArrayList<EObject>(); + merge(o, oo, useNulls ? null : json, json.has("$updateEnumWithDefault"), deleted); + for (EObject o1 : deleted) { + if (!json.has("$forcedUpdate")) + checkIfDeleteIsAllowed(o1); + if (!pe.permit(userName, "DELETE", object2ref(o1))) { + throw new RuntimeException("Update Action results in DELETE not permitted: " + userName + " " + + object2ref(o1)); + } + } + if (deleted.size() > 0) + logger.warn("update deletes: " + objects2ref(deleted)); + updateRefs(root, refs); + merge(o, oo, useNulls ? null : json, json.has("$updateEnumWithDefault"), null); + updateMetricValues(o, json); + if (saveOnCreate && !json.has("$nosave")) + save(); + return null; + } + + private void updateMetricValues(EObject o, JSONObject json) { + // String xx = json == null ? "NULL" : json.toString(2); + // System.err.println("HERE: " + object2ref(o) + " " + (xx.length() > + // 1000 ? xx.subSequence(0, 500)+"...." : xx)); + if (json == null) + return; + NamedEntity o1 = (o instanceof NamedEntity) ? (NamedEntity) o : null; + boolean changed = false; + for (EAttribute attr : o.eClass().getEAllAttributes()) { + if (!attr.getEType().getName().endsWith("MetricAttribute")) + continue; + if (!json.has(attr.getName())) + continue; + metrics.updateMetric(o, attr, json.get(attr.getName())); + changed = true; + } + // handle containment references + for (EReference ref : o.eClass().getEAllReferences()) { + if (!ref.isContainment()) + continue; + Object o2 = o.eGet(ref); + if (o2 == null) + continue; + if (ref.isMany()) { + @SuppressWarnings("unchecked") + EList<EObject> l = (EList<EObject>) o2; + for (EObject o3 : l) { + if (o3 instanceof NamedEntity) + updateMetricValues(o3, findJsonInNamedList(o3, findJsonWithName(json, ref.getName()))); + } + } else { + EObject o3 = (EObject) o2; + updateMetricValues(o3, findJsonWithName(json, ref.getName())); + } + } + if (changed && o1 != null) + o1.setLastChanged(new Date()); + } + + public static void merge(EObject o, EObject oo, JSONObject json, boolean updateEnumWithDefault, + List<EObject> deleted) { + boolean makeChange = deleted == null; + NamedEntity o1 = (o instanceof NamedEntity) ? (NamedEntity) o : null; + boolean changed = false; + if (json != null && json.has("$useNull")) + json = null; + for (EAttribute attr : oo.eClass().getEAllAttributes()) { + if (!makeChange) + continue; // TODO verify errors + EStructuralFeature f = o.eClass().getEStructuralFeature(attr.getName()); + if (!(f instanceof EAttribute)) + continue; + EAttribute attr1 = (EAttribute) f; + if (attr.getEType() != attr1.getEType()) + continue; + if (attr.getName().equals("name")) + continue; // for now. do not merge name. + Object o2 = oo.eGet(attr); + if (json != null && !json.has(attr.getName())) + continue; + // TODO handle EEnums better. If o2 is the default value do not + // update + if (!updateEnumWithDefault && attr1.getEType() instanceof EEnum) { + EEnum enum1 = (EEnum) attr1.getEType(); + if (enum1.getDefaultValue() == o2) + continue; + } + Object o3 = o.eGet(attr1); + if (!objectEquals(o2, o3)) { + o.eSet(attr1, o2); + if (o1 != null) + changed = true; + } + } + // handle non-containment references + for (EReference ref : oo.eClass().getEAllReferences()) { + if (!makeChange) + continue; // TODO verify errors + if (ref.isContainment() || ref.isContainer()) + continue; + EStructuralFeature f = o.eClass().getEStructuralFeature(ref.getName()); + if (!(f instanceof EReference)) + continue; + EReference ref1 = (EReference) f; + if (ref.getEType() != ref1.getEType()) { + logger.warn("merge cannot handle different type: " + ref.getEType() + " " + ref1.getEType()); + continue; + } + Object o2 = oo.eGet(ref); + if (json != null && !json.has(ref.getName())) + continue; + if (ref.isMany() && json != null && !json.has(ref.getName())) { + @SuppressWarnings("unchecked") + EList<EObject> l = (EList<EObject>) o2; + if (l.size() == 0) + continue; + } + Object o3 = o.eGet(ref1); + if (!objectEquals(o2, o3)) { + o.eSet(ref1, o2); + if (o1 != null) + changed = true; + } + } + // handle containment references + for (EReference ref : oo.eClass().getEAllReferences()) { + if (!ref.isContainment()) + continue; + EStructuralFeature f = o.eClass().getEStructuralFeature(ref.getName()); + if (!(f instanceof EReference)) + continue; + EReference ref1 = (EReference) f; + if (ref.getEType() != ref1.getEType()) { + logger.warn("merge containment cannot handle different type: " + ref.getEType() + " " + ref1.getEType()); + throw new RuntimeException("merge containment cannot handle different type: " + ref.getEType() + " " + + ref1.getEType()); + } + Object o2 = oo.eGet(ref); + if (json != null && !json.has(ref.getName())) + continue; + if (ref.isMany() && json != null && !json.has(ref.getName())) { + @SuppressWarnings("unchecked") + EList<EObject> l = (EList<EObject>) o2; + if (l.size() == 0) + continue; + } + Object o3 = o.eGet(ref1); + if (ref.isMany()) { + @SuppressWarnings("unchecked") + EList<EObject> l2 = (EList<EObject>) o2; + @SuppressWarnings("unchecked") + EList<EObject> l3 = (EList<EObject>) o3; + EList<EObject> l4 = new BasicEList<EObject>(); + if (l2.size() != l3.size()) + changed = true; + for (EObject oo2 : l2) { + EObject oo3 = findInNamedList(l3, oo2); + if (oo3 != null) + merge(oo3, oo2, findJsonInNamedList(oo3, findJsonWithName(json, ref.getName())), + updateEnumWithDefault, deleted); + else { + if (makeChange) { + oo3 = EcoreUtil.copy(oo2); + setCreated(oo3); + changed = true; + } + } + l4.add(oo3); + } + for (EObject oo3 : l3) { + // System.err.println("XXYYZZ: " + objects2ref(l4) + " " + + // object2ref(oo3) + " " + + // objects2ref(l4).contains(object2ref(oo3)) + " " + + // l4.contains(oo3)); + if (l4.contains(oo3)) + continue; + // oo3 deleted + if (makeChange) + changed = true; + else + deleted.add(oo3); + } + if (makeChange) { + l3.clear(); + l3.addAll(l4); + } + } else { + if (o3 == null && o2 == null) + continue; + if (o3 == null && o2 != null) { + if (makeChange) { + EObject o4 = EcoreUtil.copy((EObject) o2); + if (o2.getClass() != o4.getClass()) { + // TODO issue when o2 is a SOMF provided object. The + // Type of o4 is not done right. + System.err.println("Object copy does not preserve class: " + o2.getClass() + " -> " + + o4.getClass()); + } + setCreated(o4); + o.eSet(ref1, o4); + changed = true; + } + continue; + } + if (o3 != null && o2 == null) { + if (makeChange) { + o.eSet(ref1, null); + changed = true; + } else + deleted.add((EObject) o3); + continue; + } + merge((EObject) o3, (EObject) o2, findJsonWithName(json, ref.getName()), updateEnumWithDefault, deleted); + } + } + if (changed && o1 != null) + o1.setLastChanged(new Date()); + } + + private static void setCreated(EObject o) { + if (o == null) + return; + if (o instanceof NamedEntity) { + NamedEntity n = (NamedEntity) o; + n.setCreated(new Date()); + } + // handle containment references + for (EReference ref : o.eClass().getEAllReferences()) { + if (!ref.isContainment()) + continue; + Object o1 = o.eGet(ref); + if (ref.isMany()) { + @SuppressWarnings("unchecked") + EList<EObject> l = (EList<EObject>) o1; + for (EObject o2 : l) + setCreated(o2); + } else + setCreated((EObject) o1); + } + } + + private static JSONObject findJsonWithName(JSONObject json, String name) { + return (json != null && json.has(name)) ? json.getJSONObject(name) : null; + } + + private static JSONObject findJsonInNamedList(EObject o, Object json) { + if (o instanceof NamedEntity) { + NamedEntity o1 = (NamedEntity) o; + if (json instanceof JSONObject) { + JSONObject json1 = (JSONObject) json; + if (json1.has(o1.getName())) { + return json1.getJSONObject(o1.getName()); + } + } + } + return null; + } + + public static EObject findInNamedList(EList<? extends EObject> l, String name) { + if (name == null) + return null; + for (EObject o2 : l) { + NamedEntity n2 = (o2 instanceof NamedEntity) ? (NamedEntity) o2 : null; + if (n2 != null && name.equals(n2.getName())) + return o2; + } + return null; + } + + private static EObject findInNamedList(EList<EObject> l, EObject o) { + if (o instanceof NamedEntity) + return findInNamedList(l, ((NamedEntity) o).getName()); + return null; + } + + private static boolean objectEquals(Object o1, Object o2) { + if (o1 == null && o2 == null) + return true; + if (o1 != null && o2 == null) + return false; + if (o2 == null && o1 != null) + return false; + return o2.equals(o1); + } + + private Object delete(Subject subject) { + if (subject == null || subject.o == null) + throw new RuntimeException("Object does not exists"); + if (subject.ref != null) { + for (EObject o : ref2objects(subject.o, subject.ref)) { + checkIfDeleteIsAllowed(o); + } + if (subject.ref.isMany()) { + @SuppressWarnings("unchecked") + EList<EObject> ll = (EList<EObject>) subject.o.eGet(subject.ref); + ll.clear(); + } else { + subject.o.eSet(subject.ref, null); + } + return null; + } + if (subject.o.eContainmentFeature() == null) + throw new RuntimeException("Cannot delete root object"); + checkIfDeleteIsAllowed(subject.o); + if (subject.o.eContainmentFeature() instanceof EReference) { + EReference ref = subject.o.eContainmentFeature(); + if (ref.isMany()) { + @SuppressWarnings("unchecked") + EList<EObject> ll = (EList<EObject>) subject.o.eContainer().eGet(ref); + ll.remove(subject.o); + } else { + subject.o.eContainer().eSet(ref, null); + } + } + if (saveOnCreate) + save(); + return null; + } + + private void checkIfDeleteIsAllowed(EObject o) { + // System.err.println("checkIfDeleteIsAllowed: " + o + " size=" + + // findReferences(root, o, true).size()); + if (findReferences(root, o, true).size() > 0) { + throw new RuntimeException("Unable to delete object (references exists): " + object2ref(o)); + } + } + + private Object list(Subject subject, int levels) { + if (subject == null) { + return null; + } + if (subject.ref == null) { + return ecore2json(subject.o, levels, null, true); + } + + // isMany ref need to return a list of IDs + JSONObject json = new JSONObject(); + json.put(subject.ref.getName(), ecorelist2jsonArray(subject.o, subject.ref)); + return json; + } + + private static Object ecorelist2jsonArray(EObject o, EReference ref) { + JSONArray a = new JSONArray(); + @SuppressWarnings("unchecked") + EList<EObject> ll = (EList<EObject>) o.eGet(ref); + for (EObject oo : ll) { + a.put(ecoreId(oo)); + } + return a; + } + + private static Object ecorelist2jsonNodeArray(EObject o, EReference ref) { + JSONObject json = new JSONObject(); + JSONArray a = new JSONArray(); + json.put("$children", a); + json.put("$ordered", ref.isOrdered()); + @SuppressWarnings("unchecked") + EList<EObject> ll = (EList<EObject>) o.eGet(ref); + for (EObject oo : ll) { + a.put(ecoreId(oo)); + } + return json; + } + + private static Object ecore2jsonNode(EObject o, EReference ref) { + JSONObject json = new JSONObject(); + json.put("$isNull", o == null); + json.put("$child", ref.getName()); + json.put("$required", ref.isRequired()); + return json; + } + + private static JSONArray list2jsonArray(List<EObject> ll) { + JSONArray a = new JSONArray(); + for (EObject oo : ll) { + a.put(object2ref(oo)); + } + return a; + } + + private static JSONArray subjectList2jsonArray(List<Subject> ll) { + JSONArray a = new JSONArray(); + for (Subject subject : ll) { + JSONObject o = new JSONObject(); + o.put("path", object2ref(subject.o)); + o.put("ref", subject.ref.getName()); + a.put(o); + } + return a; + } + + public static JSONObject ecore2json(EObject o, int levels, EClass defaultClass, boolean showTransient) { + return ecore2json(o, levels, defaultClass, showTransient, false, true); + } + + public static JSONObject ecore2json(EObject o, int levels, EClass defaultClass, boolean showTransient, + boolean showNaming, boolean showEmptyLists) { + JSONObject json = new JSONObject(); + if (defaultClass == null && o.eContainer() != null) + defaultClass = (EClass) o.eContainingFeature().getEType(); + if (levels == -2000) { + json.put("$name", o.eContainer() == null ? "/" : object2ref(o)); + json.put("$class", o.eClass().getEPackage().getNsURI() + "." + o.eClass().getName()); + json.put("$time", new Date().getTime()); + json.put("$version", "1.10.0"); + } else if (o.eClass() != defaultClass) { + // object class id not default class + json.put("$class", o.eClass().getEPackage().getNsURI() + "." + o.eClass().getName()); + } + // json.put("$implClass", o.getClass().getName()); + EAttribute namingAttr = namingAttribute(o.eContainmentFeature()); + for (EAttribute attr : o.eClass().getEAllAttributes()) { + if (!showTransient && attr.isTransient()) + continue; + if (attr.getEAnnotation(PERSIST) != null) + continue; + if (!showNaming && attr == namingAttr) + continue; + // if (o instanceof NamedEntity && + // attr.getName().equals("lastChanged")) + // continue; + // if (o instanceof NamedEntity && attr.getName().equals("created")) + // continue; + if (attr.isMany()) { + if (attr.getEType().getInstanceTypeName().equals("org.eclipse.emf.ecore.util.FeatureMap$Entry")) + continue; + JSONArray a = new JSONArray(); + json.put(attr.getName(), a); + @SuppressWarnings("unchecked") + EList<Object> l = (EList<Object>) o.eGet(attr); + if (l == null) { + logger.warn("attribute list returned null: " + object2ref(o) + " " + attr.getName()); + continue; + } + for (Object oo : l) { + a.put(attr2jsonValue(levels, oo, attr.getEType())); + } + } else { + // System.out.println("HERE 99: " + o + " " + attr + " " + + // o.eGet(attr)); + json.put(attr.getName(), attr2jsonValue(levels, o.eGet(attr), attr.getEType())); + } + } + for (EReference ref : o.eClass().getEAllReferences()) { + if (ref.isContainment() || ref.isContainer()) + continue; + if (ref.isMany()) { + @SuppressWarnings("unchecked") + EList<EObject> l = (EList<EObject>) o.eGet(ref); + JSONArray a = new JSONArray(); + for (EObject oo : l) { + JSONObject json1 = new JSONObject(); + json1.put("$ref", oo == null ? "NULL" : object2ref(oo)); + a.put(json1); + } + json.put(ref.getName(), a); + } else { + EObject oo = (EObject) o.eGet(ref); + if (oo == null) + continue; + JSONObject json1 = new JSONObject(); + json1.put("$ref", object2ref(oo)); + json.put(ref.getName(), json1); + } + } + for (EReference ref : o.eClass().getEAllContainments()) { + if (ref.isMany()) { + if (levels == 0) { + json.put(ref.getName(), ecorelist2jsonArray(o, ref)); + continue; + } + if (levels < -1000) { + json.put(ref.getName(), ecorelist2jsonNodeArray(o, ref)); + continue; + } + if (levels < 0) + continue; + @SuppressWarnings("unchecked") + EList<EObject> l = (EList<EObject>) o.eGet(ref); + if (!showEmptyLists && l.size() == 0) + continue; + EAttribute f = namingAttribute(ref); + if (f != null) { + JSONObject json1 = new JSONObject(); + json.put(ref.getName(), json1); + for (EObject oo : l) { + String nn; + if (oo.eGet(f) instanceof EDataTypeEList) { + @SuppressWarnings("rawtypes") + EDataTypeEList xx = (EDataTypeEList) oo.eGet(f); + nn = xx.toString(); + System.err.println(oo.eClass().getName() + " " + f.getName() + " " + xx); + continue; + } else + nn = (String) oo.eGet(f); + if (nn == null) { + logger.warn("name is null " + oo + " " + f); + continue; + } + if (json1.has(nn)) { + System.err.println("name is already used " + nn + " " + object2ref(o) + "@" + f.getName()); + continue; + } + json1.put( + nn, + ecore2json(oo, levels - 1, ref.getEReferenceType(), showTransient, showNaming, + showEmptyLists)); + } + } else { + JSONArray a = new JSONArray(); + json.put(ref.getName(), a); + for (EObject oo : l) { + a.put(ecore2json(oo, levels - 1, ref.getEReferenceType(), showTransient)); + } + } + } else { + EObject oo = (EObject) o.eGet(ref); + if (oo != null || levels < -1) { + if (levels == 0) + json.put(ref.getName(), new JSONObject()); + else if (levels < -1000) + json.put(ref.getName(), ecore2jsonNode(oo, ref)); + else if (levels > 0) + json.put( + ref.getName(), + ecore2json(oo, levels - 1, ref.getEReferenceType(), showTransient, showNaming, + showEmptyLists)); + } + + } + } + return json; + } + + private static EAttribute namingAttribute(EReference ref) { + if (ref == null || !ref.isMany()) + return null; + EStructuralFeature f = ref.getEReferenceType().getEStructuralFeature("name"); + if (f instanceof EAttribute) { + EAttribute ff = (EAttribute) f; + if (ff.getEType().getInstanceClass().getName().equals("java.lang.String")) { + return ff; + } + } + return null; + } + + public static String object2ref(EObject oo) { + if (oo.eContainer() == null) { + return ""; + } + if (!(oo.eContainingFeature() instanceof EReference)) { + System.err.println("XXXX: oo=" + oo + " fea=" + oo.eContainingFeature()); + throw new RuntimeException("eContainingFeature not an reference: " + oo); + } + EReference ref = (EReference) oo.eContainingFeature(); + StringBuffer b = new StringBuffer(); + b.append(object2ref(oo.eContainer())); + b.append("/"); + b.append(ref.getName()); + if (ref.isMany()) { + b.append("/"); + b.append(ecoreId(oo)); + } + return b.toString(); + } + + public static List<String> objects2ref(Collection<EObject> l) { + List<String> res = new ArrayList<String>(); + for (EObject o : l) { + res.add(object2ref(o)); + } + return res; + } + + public static String relativeObject2ref(EObject o1, EObject oo) { + if (o1 == oo) + return ""; + if (oo.eContainer() == null) { + return null; + } + EReference ref = (EReference) oo.eContainingFeature(); + StringBuffer b = new StringBuffer(); + b.append(relativeObject2ref(o1, oo.eContainer())); + b.append("/"); + b.append(ref.getName()); + if (ref.isMany()) { + b.append("/"); + b.append(ecoreId(oo)); + } + return b.toString(); + } + + @SuppressWarnings({ "rawtypes" }) + private Object operation(Subject subject, String action, JSONObject json, JSONObject context) { + EObject o = subject.o; + EClass eClass = o.eClass(); + EOperation op = null; + for (EOperation op1 : eClass.getEAllOperations()) { + if (op1.getName().equals(action)) { + op = op1; + break; + } + } + if (op == null) + throw new RuntimeException("No such operation:" + action); + try { + List<Class> argTypes = new ArrayList<Class>(); + List<Object> args = new ArrayList<Object>(); + for (EParameter p : op.getEParameters()) { + if (p.getEType().getName().equals("RemoteContext")) { + // special case for getting context information (e.g. remote + // IP) to operations. + if (json.has(p.getName())) + context.put("remote", json.get(p.getName())); + args.add(context); + argTypes.add(JSONObject.class); + continue; + } + if (!json.has(p.getName())) { + logger.warn("Operation " + PropertyUtil.replaceForLogForcingProtection(action) + " has missing parameter:" + p.getName()); + } + Object oo = null; + if (p.isMany()) { + EList<Object> l = new BasicEList<Object>(); + oo = l; + if (json.has(p.getName())) { + Object o2 = json.get(p.getName()); + if (!(o2 instanceof JSONArray)) { + throw new RuntimeException("parameter need to be a Json array:" + p.getName()); + } + JSONArray a = (JSONArray) o2; + for (int i = 0; i < a.length(); i++) { + Object o3 = a.get(i); + if (p.getEType() instanceof EClass) { + EClass eClass1 = (EClass) p.getEType(); + if (!(o3 instanceof JSONObject)) + throw new RuntimeException("parameter need to be a Json object:" + p.getName()); + EObject ooo = parameterObjectFromJson(eClass1, (JSONObject) o3); + l.add(ooo); + } + if (p.getEType() instanceof EDataType) { + l.add(jsonValue2attrValue((EDataType) p.getEType(), o3)); + } + } + } + args.add(oo); + argTypes.add(EList.class); + } else { + if (json.has(p.getName())) { + Object o2 = json.get(p.getName()); + if (p.getEType() instanceof EClass) { + EClass eClass1 = (EClass) p.getEType(); + if (!(o2 instanceof JSONObject)) + throw new RuntimeException("parameter need to be a Json object:" + p.getName()); + EObject ooo = parameterObjectFromJson(eClass1, (JSONObject) o2); + oo = ooo; + } + if (p.getEType() instanceof EDataType) { + EDataType eType = (EDataType) p.getEType(); + oo = jsonValue2attrValue(eType, o2); + } + + } + args.add(oo); + argTypes.add(p.getEType().getInstanceClass()); + } + } + Class<? extends EObject> c = subject.o.getClass(); + Method m = c.getMethod(action, argTypes.toArray(new Class[argTypes.size()])); + // System.err.println("YYYY: " + o + " " + subject + " " + action + + // " " + m + " " + argTypes); + Object oo = m.invoke(o, args.toArray(new Object[args.size()])); + JSONObject res = new JSONObject(); + if (oo instanceof EList) { + EList l = (EList) oo; + JSONArray a = new JSONArray(); + for (Object ooo : l) { + if (ooo instanceof EObject) { + EObject eo = (EObject) ooo; + a.put(ecore2json(eo, 100, (EClass) op.getEType(), true, true, true)); + } else { + a.put(attr2jsonValue(0, ooo, op.getEType())); + } + } + res.put("returns", a); + } else if (oo instanceof EObject) { + EObject eo = (EObject) oo; + res.put("returns", ecore2json(eo, 100, (EClass) op.getEType(), true, true, true)); + } else { + res.put("returns", oo == null ? null : attr2jsonValue(0, oo, op.getEType())); + } + return res; + } catch (Exception e) { + JSONObject res = new JSONObject(); + if (e instanceof InvocationTargetException && e.getCause() instanceof Exception) { + e = (Exception) e.getCause(); + } + res.put("exception", e.toString()); + // res.put("location", e.getStackTrace()[1].toString()); + res.put("directory", props.get("user.dir")); + res.put("user", props.get("user.name")); + res.put("hostname", props.get("user.hostname")); + res.put("port", props.get("server.port")); + res.put("class", eClassName); + res.put("action", action); + res.put("request", json); + res.put("context", context); + if (e instanceof ManagementServerError) { + ManagementServerError ee = (ManagementServerError) e; + res.put("remote", ee.getJson()); + } else + printStackTrace(e); + List<String> args = new ArrayList<String>(); + for (EParameter p : op.getEParameters()) { + args.add(p.getEType().getName()); + } + logger.error(PropertyUtil.replaceForLogForcingProtection("operation " + action + "(" + StringUtil.join(args, ",") + ") failed requestId: " + + context.getString("requestId") + " " + e)); + throw new ManagerException(500, "operation failed: " + action + "\n" + res.toString(2)); + } + } + + private EObject parameterObjectFromJson(EClass eClass1, JSONObject json) { + if (json.has("$ref")) { + String path = (String) json.get("$ref"); + if (path.equals("NULL")) + return null; + if (path.equals("")) + return null; + Subject s = find(root, path); + if (s.o == null) + return null; + if (!eClass1.isInstance(s.o)) { + throw new RuntimeException("Bad type expected: " + eClass1.getName() + " " + path); + } + return s.o; + } + List<Ref> refs = new ArrayList<ManagementServer.Ref>(); + EObject ooo = loadObjectFromJson(eClass1.getEPackage().getEFactoryInstance(), eClass1.getName(), json, refs); + updateRefs(ooo, refs); + return ooo; + } + + @Override + public Object handleBinary(String userName, String action, String resourcePath, InputStream in) { + if (!pe.permit(userName, action, resourcePath)) + throw new RuntimeException("Action not permitted: " + userName + " " + action + " " + resourcePath); + return null; + } + + public Jetty8Client getJettyClient() { + return jettyClient; + } + + public void shutdown() { + // TODO Auto-generated method stub + + } + + public EObject getObject() { + return root; + } + + public void setObject(EObject root) { + this.root = root; + } + + int i = 0; + + public void save() { + int j = i++; + // System.err.println("XXXX save start:" + j); + save(root, "ROOT", directory, true, root.eClass()); + // System.err.println("XXXX save done:" + j); + lastSave = new Date(); + } + + private Date lastSave = null; + + public synchronized void save(long ms) { + Date now = new Date(); + if (lastSave == null || lastSave.getTime() + ms < now.getTime()) + save(); + } + + public void save(EObject o, String id, String directory, boolean singleton, EClass defClass) { + JSONObject json = ecore2json(o, -1, defClass, false); + String fname = directory + (o.eContainer() == null ? "/ROOT" : "") + ".json"; + for (EReference ref : o.eClass().getEAllContainments()) { + if (ref.isMany()) { + HashSet<String> names = new HashSet<String>(); + // Try 3 times to save list. + boolean saved = false; + for (int i = 0; i < 3; i++) { + try { + @SuppressWarnings("unchecked") + EList<EObject> l = (EList<EObject>) o.eGet(ref); + JSONArray a = new JSONArray(); + for (EObject oo : l) { + String n = ecoreId(oo); + if (names.contains(n)) { + System.err.println("name is already used " + n + " " + object2ref(o) + "@" + + ref.getName()); + } + names.add(n); + a.put(n); + String dir2 = directory + "/" + ref.getName() + "/" + n; + save(oo, null, dir2, false, ref.getEReferenceType()); + } + if (ref.isOrdered()) + json.put("$order:" + ref.getName(), a); + saved = true; + break; + } catch (ConcurrentModificationException e) { + // ManagementServerUtils.printStackTrace(e); + // logger.error("ConcurrentModificationException: " + + // o.eClass().getName() + "@" + ref.getName()); + continue; + } + } + if (!saved) { + System.err.println("unable to save object list: " + object2ref(o) + "@" + ref.getName()); + logger.error("unable to save object list: " + object2ref(o) + "@" + ref.getName()); + } + // delete no longer existing objects. + File dir = new File(directory + "/" + ref.getName()); + File[] files = dir.listFiles(); + if (files == null) + continue; + for (File f : files) { + if (f.isDirectory() && !names.contains(f.getName())) { + FileUtils.deleteDirectory(f); + } + if (f.getName().endsWith(".json")) { + String n = f.getName().substring(0, f.getName().length() - 5); + if (!names.contains(n)) { + f.delete(); + } + } + } + } else { + String dir2 = directory + "/" + ref.getName(); + EObject oo = (EObject) o.eGet(ref); + if (oo == null) { + File f = new File(dir2); + if (f.exists()) + FileUtils.deleteDirectory(f); + f = new File(dir2 + ".json"); + if (f.exists()) + f.delete(); + } else + save(oo, ecoreId(oo), dir2, true, ref.getEReferenceType()); + } + } + storeJson(fname, json); + } + + HashMap<String, String> cache = new HashMap<String, String>(); + + private synchronized void storeJson(String fname, JSONObject json) { + // TODO cache the data so we do no need to write the same all the time + // but need to support deletion of files and directory. See save(..) + // above. + // String s = json.toString(); + // if (s.equals(cache.get(fname))) return; + try { + OutputStreamWriter w = FileUtils.filename2writer(fname + ".tmp"); + w.append(json.toString(2)); + w.close(); + File f1 = new File(fname); + File f2 = new File(fname + ".tmp"); + f2.renameTo(f1); + } catch (IOException e) { + // TODO Auto-generated catch block + printStackTrace(e); + } + } + + private static String ecoreId(EObject oo) { + EStructuralFeature f = oo.eClass().getEStructuralFeature("name"); + if (f instanceof EAttribute) { + EAttribute attr = (EAttribute) f; + return (String) oo.eGet(attr); + } + if (oo.eContainer() != null) { + if (oo.eContainmentFeature().isMany()) { + @SuppressWarnings("unchecked") + EList<EObject> l = (EList<EObject>) oo.eContainer().eGet(oo.eContainmentFeature()); + return Integer.toString(l.indexOf(oo)); + } else { + return oo.eContainmentFeature().getName(); + } + } + return "id" + id++; + } + + // private String jsonId(JSONObject json2) { + // if (json2.has("name")) + // return json2.getString("name"); + // return "id" + id++; + // } + + public static Object attr2jsonValue(int levels, Object o, EClassifier eClassifier) { + if (!(eClassifier instanceof EDataType)) + return null; + EDataType t = (EDataType) eClassifier; + EFactory f = t.getEPackage().getEFactoryInstance(); + // TODO handle int and doubles. + if (levels == -3 && o == null) { + JSONObject json = new JSONObject(); + json.put("$isNull", true); + return json; + } + return f.convertToString(t, o); + } + + public static Object jsonValue2attrValue(EDataType t, Object value) { + EFactory f = t.getEPackage().getEFactoryInstance(); + // System.err.println("XXXYYZZ: " + t + " value=" + value + " " + + // value.getClass()); + if (value instanceof String && t.getInstanceClass().equals(Date.class)) { + try { + return new Date(Long.parseLong((String) value)); + } catch (NumberFormatException e) { + } + } + if (value instanceof String) { + String s = (String) value; + return f.createFromString(t, s); + } + if (value instanceof Long && t.getInstanceClass().equals(Date.class)) { + Long l = (Long) value; + return new Date(l); + } + if (value instanceof Integer && t.getInstanceClass().equals(Date.class)) { + long l = (Integer) value; + return new Date(l); + } + if (t.getInstanceClass().equals(Long.class) && value instanceof Integer) { + return Long.valueOf((Integer) value); + } + if (t.getInstanceClass().equals(long.class) && value instanceof Integer) { + return Long.valueOf((Integer) value); + } + if (t.getInstanceClass().equals(Long.class) && value instanceof Integer) { + return Long.valueOf((Integer) value); + } + if (t.getInstanceClass().equals(long.class) && value instanceof Integer) { + return Long.valueOf((Integer) value); + } + if (t.getInstanceClass().equals(String.class) && value instanceof Integer) { + return Integer.toString((int) value); + } + if (t.getInstanceClass().equals(String.class) && value instanceof Double) { + return Double.toString((double) value); + } + if (t.getInstanceClass().equals(String.class) && value instanceof Long) { + return Long.toString((long) value); + } + if (t.getInstanceClass().equals(String.class) && value instanceof Boolean) { + return Boolean.toString((boolean) value); + } + if (value instanceof Integer || value instanceof Double || value instanceof Long || value instanceof Boolean) { + return value; + } + return null; + } + + private Object stringValue2attrValue(EDataType t, String s) { + EFactory f = t.getEPackage().getEFactoryInstance(); + return f.createFromString(t, s); + } + + class Ref { + public Ref(EObject o, EReference ref, Object object) { + super(); + this.o = o; + this.ref = ref; + this.json = (JSONObject) object; // TODO handle error cases + } + + EObject o; + EReference ref; + JSONObject json; + + @Override + public String toString() { + return "Ref [o=" + o + ", ref=" + ref + ", json=" + json + "]"; + } + } + + private void handleReference(EObject o, JSONObject json, List<Ref> refs) { + // System.out.println ("AAAAupdate : " + object2ref(o) + " " + + // json.toString(2)); + for (EReference ref : o.eClass().getEAllReferences()) { + if (!json.has(ref.getName())) + continue; + if (ref.isContainer()) + continue; + if (ref.isContainment()) { + if (json.has("$version") || jsonHasVersion(json.get(ref.getName()))) + continue; + if (ref.isMany()) { + Object x = json.get(ref.getName()); + @SuppressWarnings("unchecked") + EList<EObject> l = (EList<EObject>) o.eGet(ref); + if (x instanceof JSONObject) { + EAttribute f = namingAttribute(ref); + JSONObject o1 = (JSONObject) x; + for (EObject oo : l) { + handleReference(oo, o1.getJSONObject((String) oo.eGet(f)), refs); + } + } else { + JSONArray a = (JSONArray) x; + int i = 0; + for (EObject oo : l) { + handleReference(oo, a.getJSONObject(i), refs); + i++; + } + } + } else { + EObject oo = (EObject) o.eGet(ref); + if (oo == null) continue; + Object oo1 = json.get(ref.getName()); + if (oo1 != null && oo1.getClass().getCanonicalName().equals("org.json.JSONObject.Null")) { + oo1 = null; + } + if (oo1 instanceof JSONObject || oo1 == null) { + handleReference(oo, (JSONObject) oo1, refs); + continue; + } + throw new RuntimeException("Unable to handle reference: " + ref.getName() + + " " + oo1.getClass().getCanonicalName()); + } + continue; + } + // is reference + if (ref.isMany()) { + Object aa = json.get(ref.getName()); + if (aa instanceof JSONArray) { + JSONArray a = (JSONArray) aa; + for (int i = 0; i < a.length(); i++) { + refs.add(new Ref(o, ref, a.get(i))); + } + } + } else { + refs.add(new Ref(o, ref, json.get(ref.getName()))); + } + + } + // System.out.println ("AAAAupdate : " + object2ref(o) + " " + refs); + } + + private boolean jsonHasVersion(Object object) { + if (object instanceof JSONObject) { + JSONObject json = (JSONObject) object; + if (json.has("$version") || json.has("$child") || json.has("$children")) + return true; + for (Iterator<String> i = json.keys(); i.hasNext();) { + String s = i.next(); + if (jsonHasVersion(json.get(s))) + return true; + } + } + if (object instanceof JSONArray) { + JSONArray a = (JSONArray) object; + for (int i = 0; i < a.length(); i++) { + if (jsonHasVersion(a.get(i))) + return true; + } + } + return false; + } + + private void updateRefs(EObject res, List<Ref> refs) { + for (Ref x : refs) { + // System.out.println("REF: " + ref2name(x.ref) + " " + x.json); + // TODO handle error better. + if (!x.json.has("$ref")) + continue; + String path = (String) x.json.get("$ref"); + if (path.equals("NULL")) + continue; + if (path.equals("")) + continue; + EObject root1 = res; + if (x.json.has("$refroot")) { + // Not tested + String rootpath = (String) x.json.get("$refroot"); + System.err.println("XXXX using new root: " + rootpath); + if (!rootpath.equals("NULL") && !rootpath.equals("")) { + Subject s1 = find(root, rootpath); + System.err.println("XXXX using new root: " + s1); + if (s1 == null || s1.o != null) { + root1 = s1.o; + System.err.println("XXXX using new root: " + root1); + } + } + } + Subject s = find(root1, path); + if (s == null || s.ref != null) { + logger.warn("Unable to determine reference for:" + PropertyUtil.replaceForLogForcingProtection(path)); + continue; + } + if (x.ref.isMany()) { + @SuppressWarnings("unchecked") + EList<EObject> l = (EList<EObject>) x.o.eGet(x.ref); + l.add(s.o); + } else { + try { + // System.out.println("XXX:" + object2ref(x.o) + " " + + // object2ref(s.o)); + x.o.eSet(x.ref, s.o); + } catch (Exception e) { + // System.out.println("Bad Reference:" + x.o); + // System.out.println("Bad Reference:" + x.ref + " " + + // x.ref.getEContainingClass()); + // System.out.println("Bad Reference:" + s.o); + logger.warn("Bad Reference:" + path + " " + x.json + " " + e); + } + } + } + } + + public static JSONObject params2json(EOperation operation, Object[] params) { + if (params.length != operation.getEParameters().size()) { + String n = operation.getEContainingClass().getName() + "@" + operation.getName(); + throw new RuntimeException("Wrong number of arguments for " + n + " got " + params.length + " expected " + + operation.getEParameters().size()); + } + JSONObject json = new JSONObject(); + for (int i = 0; i < params.length; i++) { + EParameter p = operation.getEParameters().get(i); + if (p.getEType() instanceof EClass) { + EClass eClass = (EClass) p.getEType(); + if (p.isMany()) { + @SuppressWarnings("unchecked") + List<Object> l = (List<Object>) params[i]; + JSONArray a = new JSONArray(); + for (Object oo : l) { + a.put(object2json(oo, 100, eClass, true)); + } + json.put(p.getName(), a); + } else { + json.put(p.getName(), object2json(params[i], 100, eClass, true)); + } + + } else { + if (p.isMany()) { + JSONArray a = new JSONArray(); + json.put(p.getName(), a); + @SuppressWarnings("unchecked") + List<Object> l = (List<Object>) params[i]; + for (Object oo : l) { + a.put(attr2jsonValue(0, oo, p.getEType())); + } + } else + json.put(p.getName(), attr2jsonValue(0, params[i], p.getEType())); + } + } + return json; + } + + private static JSONObject object2json(Object o, int i, EClass eClass, boolean b) { + if (o instanceof EObject) { + return ecore2json((EObject) o, i, eClass, b); + } + if (o instanceof JSONObject) { + return (JSONObject) o; + } + if (o == null) + return null; + throw new RuntimeException("Unable to convert object to json: " + o); + } + + static ManagementServer staticServer = new ManagementServer(); + + public static Object json2response(EOperation operation, JSONObject res) { + if (res == null) + return null; + if (res.length() == 0) + return null; // TODO Handle this better. + if (res.has("returns")) { + if (operation.getEType() instanceof EClass) { + EClass eClass = (EClass) operation.getEType(); + if (operation.isMany()) { + EList<EObject> l = new BasicEList<EObject>(); + JSONArray a = res.getJSONArray("returns"); + for (int i = 0; i < a.length(); i++) { + l.add(staticServer.json2ecore(eClass, a.getJSONObject(i))); + } + return l; + } else { + return staticServer.json2ecore(eClass, res.getJSONObject("returns")); + } + } else { + EDataType eType = (EDataType) operation.getEType(); + if (operation.isMany()) { + EList<Object> l = new BasicEList<Object>(); + JSONArray a = res.getJSONArray("returns"); + for (int i = 0; i < a.length(); i++) { + l.add(jsonValue2attrValue(eType, a.get(i))); + } + return l; + } else { + return jsonValue2attrValue(eType, res.get("returns")); + } + } + } + throw new ManagementServerError("remote error", res); + } + + public static String expandPath(EObject o, String pattern, String prefix) { + // E.g. "foobar/${@name}" + String x = prefix.equals("$") ? "\\" : ""; + Pattern p = Pattern.compile("(" + x + prefix + "\\{.*?})"); + Matcher m = p.matcher(pattern); + StringBuffer s = new StringBuffer(); + while (m.find()) { + String k = m.group(1); + String k1 = k.substring(2, k.length() - 1); + try { + Subject subject = find(o, k1); + if (subject == null || subject.o == null || subject.attr == null) + throw new RuntimeException("unable to resolve path: " + k1 + " on " + o); + m.appendReplacement(s, (String) subject.o.eGet(subject.attr)); + } catch (Exception e) { + logger.warn("bad expansion: " + e); + m.appendReplacement(s, x + k); + } + } + m.appendTail(s); + return s.toString(); + } + + public static OperationalState getOperationalState(EObject a) { + if (a instanceof HasOperationalState) { + HasOperationalState o1 = (HasOperationalState) a; + if (o1.getOperationalState() == OperationalState.SUSPENDED) + return OperationalState.SUSPENDED; + } + if (a.eContainer() != null) { + if (getOperationalState(a.eContainer()) == OperationalState.SUSPENDED) + return OperationalState.SUSPENDED; + } + return OperationalState.OPERATIONAL; + } + + public static boolean isSuspended(EObject o, String message) { + if (getOperationalState(o) == OperationalState.SUSPENDED) { + logger.warn("Suspended: " + message); + return true; + } + return false; + } + + public static boolean refIsNamed(EReference ref) { + // System.err.println("ZZZ : " + ref + " " + ref.getEReferenceType() + // + " " + + // ref.getEReferenceType().isSuperTypeOf(ModelPackage.eINSTANCE.getNamedEntity()) + // + " " + + // ModelPackage.eINSTANCE.getNamedEntity().isSuperTypeOf(ref.getEReferenceType()) + // ); + return true; + } + + public DroolsRuntime getDroolsRuntime() { + return droolsRuntime; + } + + public void setDroolsRuntime(DroolsRuntime droolsRuntime) { + this.droolsRuntime = droolsRuntime; + } + + // ECOMP on ECOMP + public void recordApi(String parentTransactionId, EObject o, String action, ApiRequestStatus status, long duration, + Object... params) { + if (!(root instanceof AbstractManagementServer)) + return; + Api api = findApi(o, action); + switch (status) { + case ERROR: + metrics.addIncreasingULongMetric(api, "numberOfErrorRequests", 1L, false); + break; + case START: + metrics.addIncreasingULongMetric(api, "numberOfRequests", 1L, false); + break; + case OKAY: + metrics.addIncreasingULongMetric(api, "numberOfCompletedRequests", 1L, false); + metrics.setLongMetric(api, "lastRequestDuration", duration, false); + break; + case INPROGRESS: + break; + default: + break; + } + } + + public void recordPolicyFire(String droolsRuntime, String ruleName) { + } + + public void recordPolicyObjectChange(String droolsRuntime, Object o, DroolsObjectChange changeType) { + } + + private synchronized Api findApi(EObject o, String action) { + AbstractManagementServer a = (AbstractManagementServer) root; + if (a.getComponent() == null) { + a.setComponent(ComponentFactory.eINSTANCE.createComponent()); + } + String n = o.eClass().getInstanceClassName(); + ComponentClass c = (ComponentClass) findWithName(a.getComponent().getClasses(), n); + if (c == null) { + c = ComponentFactory.eINSTANCE.createComponentClass(); + c.setName(n); + a.getComponent().getClasses().add(c); + } + Api api = (Api) findWithName(c.getApis(), action); + if (api == null) { + api = ComponentFactory.eINSTANCE.createApi(); + api.setName(action); + c.getApis().add(api); + } + return api; + } + + public static EObject findWithName(EList<? extends NamedEntity> l, String name) { + for (NamedEntity n : l) { + if (n.getName().equals(name)) + return n; + } + return null; + } + + @SuppressWarnings("unchecked") + public static void copy(EObject o, EObject o1) { + for (EAttribute attr1 : o1.eClass().getEAllAttributes()) { + EStructuralFeature f = o.eClass().getEStructuralFeature(attr1.getName()); + System.out.println("DDDDD " + attr1 + " f=" + f); + if (f instanceof EAttribute) { + EAttribute attr = (EAttribute) f; + System.out.println("DDDDD " + attr + " " + o.eGet(attr)); + o1.eSet(attr1, o.eGet(attr)); + } + } + for (EReference ref1 : o1.eClass().getEAllContainments()) { + EStructuralFeature f = o.eClass().getEStructuralFeature(ref1.getName()); + if (f instanceof EReference) { + EReference ref = (EReference) f; + if (ref1.isMany()) + o1.eSet(ref1, EcoreUtil.copyAll((EList<EObject>) o.eGet(ref))); + else + o1.eSet(ref1, EcoreUtil.copy((EObject) o.eGet(ref))); + } + } + + } + + public static JSONObject ensureHardUpdate(EObject o2, int levels) { + JSONObject json = ManagementServer.ecore2json(o2, 1000, null, true); + ensureHardUpdate(json, levels); + return json; + } + + private static void ensureHardUpdate(JSONObject json, int levels) { + if (levels <= 0) { + json.put("$useNull", 1); + return; + } + for (Iterator<String> i = json.keys(); i.hasNext();) { + Object o = json.get(i.next()); + if (o instanceof JSONObject) { + ensureHardUpdate((JSONObject) o, levels - 1); + } + if (o instanceof JSONArray) { + JSONArray a = (JSONArray) o; + for (int j = 0; j < a.length(); j++) { + if (a.get(j) instanceof JSONObject) { + ensureHardUpdate((JSONObject) a.get(j), levels - 1); + } + } + } + + } + } + + public static void decryptPasswords(EObject o) { + for (EAttribute attr : o.eClass().getEAllAttributes()) { + if (! attr.getEType().getName().equals("EString")) continue; + if (attr.isMany()) continue; + String v = (String) o.eGet(attr); + if (v != null && v.startsWith("rsa:")) { + o.eSet(attr, JavaHttpClient.decryptPassword(v)); + } + } + for (EReference ref : o.eClass().getEAllContainments()) { + if (ref.isMany()) { + @SuppressWarnings("unchecked") + EList<EObject> l = (EList<EObject>) o.eGet(ref); + for (EObject oo : l) { + decryptPasswords(oo); + } + } else { + EObject oo = (EObject) o.eGet(ref); + decryptPasswords(oo); + } + } + } + + public JSONObject getSwaggerJson() { + try { + SwaggerUtils swagger = new SwaggerUtils(); + ISwaggerHandler handler = this; + if (root instanceof ISwaggerHandler) { + handler = (ISwaggerHandler) root; + } + System.err.println("SWAGGER: Start"); + handler.updateSwagger("/resources", swagger); + System.err.println("SWAGGER: Done"); + JSONObject json = swagger.toJson(); + System.err.println("SWAGGER: " + json.toString(2)); + return json; + } catch (Exception e) { + System.err.println("SWAGGER: Error" + e); + e.printStackTrace(); + throw e; + } + } + + @Override + public void updateSwagger(String path, SwaggerUtils swagger) { + swagger.addTag(path, "Server Configuration",root); + } +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ManagementServerError.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ManagementServerError.java new file mode 100644 index 0000000..1b083f1 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ManagementServerError.java @@ -0,0 +1,43 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager;
+
+import org.json.JSONObject;
+
+public class ManagementServerError extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+ private JSONObject json;
+ public ManagementServerError(String string, JSONObject res) {
+ super(string);
+ setJson(res);
+ }
+ @Override
+ public String toString() {
+ return super.toString() + " " + getJson().toString(2);
+ }
+ public JSONObject getJson() {
+ return json;
+ }
+ public void setJson(JSONObject json) {
+ this.json = json;
+ }
+}
diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ManagementServerUtils.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ManagementServerUtils.java new file mode 100644 index 0000000..3bdd458 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ManagementServerUtils.java @@ -0,0 +1,71 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.log4j.PatternLayout;
+import org.apache.log4j.RollingFileAppender;
+
+public class ManagementServerUtils {
+ public static final Logger logger = Logger.getLogger(ManagementServerUtils.class);
+
+ public static void printStackTrace(Exception e) {
+ System.err.println(new Date().toString() + " " + e);
+ e.printStackTrace();
+ }
+
+ static HashMap<String, Logger> name2logger = new HashMap<String, Logger>();
+ public static Logger createLogger(String name, String level, String pattern) {
+ return(createLogger(name, level, pattern, "logs"));
+ }
+ public static synchronized Logger createLogger(String name, String level, String pattern, String logdir) {
+ if (name2logger.get(name) == null) {
+ Logger l = Logger.getLogger(name);
+ try {
+ RollingFileAppender a;
+ a = new RollingFileAppender(new PatternLayout(pattern), logdir + "/" + name + ".log", true);
+ a.setName(name);
+ a.setMaxFileSize("50MB");
+ a.setMaxBackupIndex(5);
+ Level ll = Level.toLevel(level.toUpperCase());
+ a.setThreshold(ll);
+ a.setAppend(true);
+ a.activateOptions();
+ l.addAppender(a);
+ l.setLevel(ll);
+ l.setAdditivity(false);
+ } catch (IOException e) {
+ logger.error("unable to create logger:" + e);
+ e.printStackTrace();
+ }
+ name2logger.put(name, l);
+ }
+ return name2logger.get(name);
+ }
+
+
+}
diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ManagerException.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ManagerException.java new file mode 100644 index 0000000..73d71e8 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ManagerException.java @@ -0,0 +1,32 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager; + +public class ManagerException extends RuntimeException { + private static final long serialVersionUID = 6430311726555738610L; + int code; + public ManagerException(int code,String message) { + super(message); + this.code = code; + } + +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ModuleReporter.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ModuleReporter.java new file mode 100644 index 0000000..f68a7e6 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/ModuleReporter.java @@ -0,0 +1,144 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.log4j.Logger;
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+
+import org.openecomp.ncomp.sirius.manager.properties.AbstractProperty;
+import org.openecomp.ncomp.sirius.manager.properties.Module;
+import org.openecomp.ncomp.sirius.manager.properties.ModuleProperty;
+import org.openecomp.ncomp.sirius.manager.properties.PropertiesFactory;
+import org.openecomp.ncomp.sirius.manager.server.SouthBoundApi;
+import org.openecomp.ncomp.utils.StringUtil;
+import org.openecomp.ncomp.webservice.utils.FileUtils;
+
+public class ModuleReporter implements Runnable {
+ public static final Logger logger = Logger.getLogger(ModuleReporter.class);
+ private SouthBoundApi api;
+ private List<ModuleReporter> submodules = new ArrayList<ModuleReporter>();
+ private ModuleReporter parent;
+ private String jarName;
+ private String name;
+ private String version;
+ private String file;
+ private String command;
+ private Properties props;
+
+
+ public ModuleReporter(SouthBoundApi api, String name, String jarName) {
+ super();
+ this.api = api;
+ this.name = name;
+ this.jarName = jarName;
+ }
+ public ModuleReporter(SouthBoundApi api, String name, String jarName, String file, String command, String version) {
+ super();
+ this.api = api;
+ this.name = name;
+ this.jarName = jarName;
+ this.file = file;
+ this.command = command;
+ this.version = version;
+ }
+ public void addSubmodule(String jarName) {
+ addSubmodule(jarName,jarName,null,null,"${version}");
+ }
+ public void addSubmodule(String name, String jarName, String file, String command, String version) {
+ ModuleReporter m=new ModuleReporter(null, name, jarName, file, command, version);
+ submodules.add(m);
+ m.parent = this;
+ }
+
+ public void start() {
+ Thread t = new Thread(this,"module reporter: " + name);
+ t.start();
+ }
+
+ @Override
+ public void run() {
+ boolean first = true;
+ while (true) {
+ try {
+// System.err.println("HERE: ");
+ if (!first) Thread.sleep(300000); // sleep 5 minutes.
+ else first = false;
+ EList<AbstractProperty> l = new BasicEList<AbstractProperty>();
+ ModuleProperty m = PropertiesFactory.eINSTANCE.createModuleProperty();
+ m.setName(name);
+ m.setVersion(version());
+ for (ModuleReporter s : submodules) {
+ Module m1 = PropertiesFactory.eINSTANCE.createModule();
+ m1.setName(s.name);
+ m1.setVersion(s.version());
+ m.getSubModules().add(m1);
+ }
+// System.err.println("HERE: " + ManagementServer.ecore2json(m, 100, null, true).toString(2));
+ l.add(m);
+ api.properties(null, l);
+ }
+ catch (Exception e) {
+ ManagementServerUtils.printStackTrace(e);
+ }
+ }
+ }
+ private String version() {
+ InputStream inputStream;
+ if (jarName == null && file == null && command == null) {
+ if (parent == null || parent.props == null)
+ return "unable to determine version for " + name + " no parent information";
+ return StringUtil.expandUsingProperties(version, parent.props, "$");
+ }
+ if (jarName != null )
+ inputStream = ModuleReporter.class.getClassLoader().getResourceAsStream(jarName + ".buildinfo");
+ else {
+ if (file != null) {
+ inputStream = FileUtils.filename2stream(file, null);
+ if (inputStream == null) logger.warn("unable to find file " + file);
+ }
+ else {
+ inputStream = FileUtils.cmd2stream(command);
+ if (inputStream == null) logger.warn("unable to run command " + command);
+ }
+ }
+ if (inputStream == null) {
+ return "unable to determine version for " + name;
+ }
+ props = new Properties();
+ try {
+ props.load(inputStream);
+ inputStream.close();
+ } catch (Exception e) {
+ logger.warn("No build info for module: " + name);
+ ManagementServerUtils.printStackTrace(e);
+ return "unable to determine version for " + name;
+ }
+ return StringUtil.expandUsingProperties(version, props, "$");
+ }
+
+}
diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/SimplePolicyEngine.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/SimplePolicyEngine.java new file mode 100644 index 0000000..5c85f6c --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/SimplePolicyEngine.java @@ -0,0 +1,34 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager; + +import org.apache.log4j.Logger; + +public class SimplePolicyEngine implements IPolicyEngine { + public static final Logger logger = Logger.getLogger(SimplePolicyEngine.class); + @Override + public boolean permit(String subject, String action, String resourcePath) { + logger.debug("Policy: " + subject + " " + action + " " + resourcePath); + return true; + } + +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/Subject.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/Subject.java new file mode 100644 index 0000000..fdb045a --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/Subject.java @@ -0,0 +1,57 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; + +public class Subject { + @Override + public String toString() { + return "Subject [o=" + o + ", ref=" + ref + ", attr=" + attr + "]"; + } + public Subject(EObject o, EReference ref) { + this.o = o; + this.ref = ref; + } + public Subject(EObject o, String refName) { + this.o = o; + ref = (EReference) o.eClass().getEStructuralFeature(refName); + if (ref == null) { + throw new RuntimeException("No such ref " + refName + " in type " + o.eClass().getName()); + } + } + + public Subject(EObject o) { + this.o = o; + } + + public Subject(EObject o, EAttribute attr) { + this.o = o; + this.attr = attr; + } + + public EObject o; + public EReference ref = null; + public EAttribute attr = null; +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/SwaggerUtils.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/SwaggerUtils.java new file mode 100644 index 0000000..b4581b9 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/SwaggerUtils.java @@ -0,0 +1,919 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager; + +// TODO +// operations - need to handle body parameter definitions +// create object - HTTP access control (CORS) issue +// update object - HTTP access control (CORS) issue +// ignore subtrees eg. /foo/component/droolsRuntimes +// handle AbstractManagementServer generically. +// Swagger annotations +// Swagger definitions +// Better handle inheritance + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStreamWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EOperation; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EPackage.Registry; +import org.eclipse.emf.ecore.EParameter; +import org.eclipse.emf.ecore.EReference; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import org.openecomp.ncomp.component.ComponentFactory; +import org.openecomp.ncomp.sirius.manager.server.AbstractManagementServer; +import org.openecomp.ncomp.sirius.manager.server.ServerFactory; +import org.openecomp.ncomp.sirius.manager.swagger.SwaggerFactory; +import org.openecomp.ncomp.sirius.manager.swagger.SwaggerModel; +import org.openecomp.ncomp.sirius.manager.swagger.SwaggerNamedObjectType; +import org.openecomp.ncomp.sirius.manager.swagger.SwaggerObjectClassDefinition; +import org.openecomp.ncomp.sirius.manager.swagger.SwaggerObjectType; +import org.openecomp.ncomp.sirius.manager.swagger.SwaggerOperation; +import org.openecomp.ncomp.sirius.manager.swagger.SwaggerParameter; +import org.openecomp.ncomp.sirius.manager.swagger.SwaggerParameterType; +import org.openecomp.ncomp.sirius.manager.swagger.SwaggerPath; +import org.openecomp.ncomp.sirius.manager.swagger.SwaggerReferenceObjectType; +import org.openecomp.ncomp.sirius.manager.swagger.SwaggerSimpleObjectType; +import org.openecomp.ncomp.sirius.manager.swagger.SwaggerTag; +import org.openecomp.ncomp.webservice.utils.FileUtils; +import org.openecomp.ncomp.webservice.utils.JsonUtils; + +public class SwaggerUtils { + + SwaggerModel m; + Map<String, Object> done = new HashMap<String, Object>(); + private boolean rootTagAdded = false; + + public SwaggerUtils() { + m = SwaggerFactory.eINSTANCE.createSwaggerModel(); + try { + JSONObject json = new JSONObject(getTemplate("swagger-api.json")); + ManagementServer s1 = new ManagementServer(); + s1.setObject(SwaggerFactory.eINSTANCE.createSwaggerModel()); + m = json2swagger(s1, json); + } catch (Exception e) { + m = SwaggerFactory.eINSTANCE.createSwaggerModel(); + } + } + + public static void main(String[] args) throws IOException { +// test("/home/ncomp/swagger.json2"); + // testClass(ServerPackage.eINSTANCE.getAbstractManagementServer()); + test2(); + + } + + private static void test2() { + SwaggerUtils u = new SwaggerUtils(); + AbstractManagementServer s = ServerFactory.eINSTANCE.createAbstractManagementServer(); + s.setConfiguration(ServerFactory.eINSTANCE.createAbstractManagementServerConfiguration()); + s.setComponent(ComponentFactory.eINSTANCE.createComponent()); + u.addTag("/foo/configuration", "The Config Tag"); + u.addTag("/foo/component", "The Component Tag"); + u.addTag("/foo", "The Foo Tag"); + u.autoAdd("/foo", s.eClass(), 2); + System.out.println(u.toJson().toString(2)); + } + + @SuppressWarnings("unused") + private static void test(String test) throws IOException { + JSONObject json0 = JsonUtils.file2json(test); + JSONObject json = JsonUtils.file2json(test); + ManagementServer s = new ManagementServer(); + s.setObject(SwaggerFactory.eINSTANCE.createSwaggerModel()); + SwaggerModel m = json2swagger(s, json); + JSONObject json1 = swagger2json(m); + // System.out.println(json1.toString(2)); + OutputStreamWriter w = FileUtils.filename2writer("target/after.json"); + w.append(json1.toString(2)); + w.close(); + w = FileUtils.filename2writer("target/before.json"); + w.append(json0.toString(2)); + w.close(); + } + + private static void testClass(EClass c) throws JSONException, IOException { + SwaggerModel m = SwaggerFactory.eINSTANCE.createSwaggerModel(); + try { + JSONObject json = new JSONObject(getTemplate("swagger-api.json")); + ManagementServer s1 = new ManagementServer(); + s1.setObject(SwaggerFactory.eINSTANCE.createSwaggerModel()); + m = json2swagger(s1, json); + } catch (Exception e) { + throw new RuntimeException("Unable to create initial Swagger object: " + e, e); + } + Map<String, Object> done = new HashMap<String, Object>(); + eclass2swagger("/foo", c, m, done); + System.out.print(swagger2json(m).toString(2)); + } + + private static SwaggerModel json2swagger(ManagementServer s, JSONObject json) throws IOException { + JSONObject paths = json.getJSONObject("paths"); + for (Iterator<String> i1 = paths.keys(); i1.hasNext();) { + String k = i1.next(); + JSONObject methods = paths.getJSONObject(k); + JSONObject json1 = new JSONObject(); + paths.put(k, json1); + json1.put("methods", methods); + for (Iterator<String> i2 = methods.keys(); i2.hasNext();) { + String k2 = i2.next(); + JSONObject method = methods.getJSONObject(k2); + if (method.has("parameters")) { + JSONArray parameters = method.getJSONArray("parameters"); + JSONObject parameters1 = new JSONObject(); + method.put("parameters", parameters1); + for (int i3 = 0; i3 < parameters.length(); i3++) { + JSONObject parameter = parameters.getJSONObject(i3); + JSONObject parameter1 = new JSONObject(); + parameters1.put(parameter.getString("name"), parameter1); + parameter1.put("type", parameter); + parameter1.put("in", parameter.getString("in")); + parameter.remove("in"); + handleParameter(parameter); + } + } + if (method.has("security")) { + JSONArray security = method.getJSONArray("security"); + JSONArray a = new JSONArray(); + method.put("security", a); + for (int i3 = 0; i3 < security.length(); i3++) { + JSONObject security1 = security.getJSONObject(i3); + JSONObject j3 = new JSONObject(); + JSONObject j31 = new JSONObject(); + j3.put("list", j31); + a.put(j3); + for (Iterator<String> i4 = security1.keys(); i4.hasNext();) { + String k4 = i4.next(); + JSONObject j4 = new JSONObject(); + j4.put("name", k4); + j4.put("roles", security1.getJSONArray(k4)); + j31.put(k4, j4); + } + } + } + if (method.has("responses")) { + JSONObject responses = method.getJSONObject("responses"); + for (Iterator<String> i3 = responses.keys(); i3.hasNext();) { + String k3 = i3.next(); + JSONObject response = responses.getJSONObject(k3); + if (response.has("schema")) { + handleParameter(response.getJSONObject("schema")); + } + } + + } + } + } + if (json.has("definitions")) { + JSONObject definitions = json.getJSONObject("definitions"); + for (Iterator<String> i2 = definitions.keys(); i2.hasNext();) { + String k2 = i2.next(); + JSONObject objectType = definitions.getJSONObject(k2); + handleParameter(objectType); + JSONObject properties = objectType.getJSONObject("properties"); + for (Iterator<String> i3 = properties.keys(); i3.hasNext();) { + String k3 = i3.next(); + JSONObject property = properties.getJSONObject(k3); + handleParameter(property); + } + } + } + OutputStreamWriter w = FileUtils.filename2writer("target/middle.json"); + w.append(json.toString(2)); + w.close(); + // System.err.println(json.toString(2)); + s.update("", s.find("/"), json, true); + System.err.println("SWAGGER: " + "=============================================="); + s.update("", s.find("/"), json, true); + // SwaggerModel res = (SwaggerModel) + // s.json2ecore(SwaggerPackage.eINSTANCE.getSwaggerModel(), json); + return (SwaggerModel) s.getObject(); + } + + private static void handleParameter(JSONObject parameter) { + if (parameter.has("items")) { + parameter.put("many", "true"); + JSONObject items = parameter.getJSONObject("items"); + copy(items, parameter, "type"); + copy(items, parameter, "enum"); + copy(items, parameter, "default"); + copy(items, parameter, "$ref"); + parameter.remove("items"); + } + if (parameter.has("schema")) { + JSONObject schema = parameter.getJSONObject("schema"); + if (schema.has("$ref")) { + copy(schema, parameter, "$ref"); + if (schema.has("type") && schema.getString("type").equals("array")) + parameter.put("many", "true"); + } else { + JSONObject items = schema.getJSONObject("items"); + parameter.put("many", "true"); + copy(items, parameter, "$ref"); + } + parameter.remove("schema"); + } + + if (parameter.has("enum")) { + parameter.put("$class", "org.openecomp.ncomp.sirius.manager.swagger.SwaggerEnumObjectType"); + return; + } + if (parameter.has("$ref")) { + JSONObject r = new JSONObject(); + r.put("$ref", parameter.getString("$ref").substring(1)); + parameter.put("reference", r); + parameter.remove("$ref"); + parameter.put("$class", "org.openecomp.ncomp.sirius.manager.swagger.SwaggerReferenceObjectType"); + return; + } + if (parameter.has("type") && parameter.get("type").equals("object")) { + parameter.put("$class", "org.openecomp.ncomp.sirius.manager.swagger.SwaggerObjectClassDefinition"); + return; + } + parameter.put("$class", "org.openecomp.ncomp.sirius.manager.swagger.SwaggerSimpleObjectType"); + if (parameter.has("additionalProperties")) { + handleParameter(parameter.getJSONObject("additionalProperties")); + } + + } + + private static JSONObject swagger2json(SwaggerModel m) throws IOException { + JSONObject json = ManagementServer.ecore2json(m, 1000, null, true); + OutputStreamWriter w = FileUtils.filename2writer("target/middle2.json"); + w.append(json.toString(2)); + w.close(); + convertFromObjectToArray(json, "tags", "name"); + json.remove("$class"); + // paths + JSONObject paths = json.getJSONObject("paths"); + for (Iterator<String> i1 = paths.keys(); i1.hasNext();) { + String k = i1.next(); + JSONObject methods1 = paths.getJSONObject(k); + JSONObject methods = methods1.getJSONObject("methods"); + paths.put(k, methods); + for (Iterator<String> i2 = methods.keys(); i2.hasNext();) { + String k2 = i2.next(); + JSONObject method = methods.getJSONObject(k2); + removeDefault(method, "deprecated", "false"); + if (method.has("deprecated")) + method.put("deprecated", true); + method.remove("lastChanged"); + removeEmptyList(method, "consumes"); + removeEmptyList(method, "produces"); + if (method.has("parameters")) { + JSONObject parameters = method.getJSONObject("parameters"); + for (Iterator<String> i3 = parameters.keys(); i3.hasNext();) { + String k3 = i3.next(); + JSONObject parameter = parameters.getJSONObject(k3); + handleParameter2(parameter); + } + convertFromObjectToArray(method, "parameters", "name"); + } + // security + // System.err.println("SWAGGER: " + "METHOD: " + + // method.toString(2)); + JSONArray security = method.getJSONArray("security"); + JSONArray a = new JSONArray(); + method.put("security", a); + for (int i3 = 0; i3 < security.length(); i3++) { + JSONObject ss = security.getJSONObject(i3).getJSONObject("list"); + JSONObject jj = new JSONObject(); + a.put(jj); + for (Iterator<String> i4 = ss.keys(); i4.hasNext();) { + String k4 = i4.next(); + ss.getJSONObject(k4); + jj.put(k4, ss.getJSONObject(k4).getJSONArray("roles")); + } + } + removeEmptyList(method, "security"); + // responses + JSONObject responses = method.getJSONObject("responses"); + for (Iterator<String> i3 = responses.keys(); i3.hasNext();) { + String k3 = i3.next(); + JSONObject response = responses.getJSONObject(k3); + response.remove("lastChanged"); + if (response.has("schema")) { + handleDefinition2(response.getJSONObject("schema")); + } + JSONObject headers = response.getJSONObject("headers"); + for (Iterator<String> i4 = headers.keys(); i4.hasNext();) { + String k4 = i4.next(); + handleDefinition2(headers.getJSONObject(k4)); + } + removeEmptyObject(response, "headers"); + } + } + } + // definitions + if (json.has("definitions")) { + JSONObject definitions = json.getJSONObject("definitions"); + for (Iterator<String> i2 = definitions.keys(); i2.hasNext();) { + String k2 = i2.next(); + JSONObject objectType = definitions.getJSONObject(k2); + handleDefinition2(objectType); + if (objectType.has("properties")) { + JSONObject properties = objectType.getJSONObject("properties"); + for (Iterator<String> i3 = properties.keys(); i3.hasNext();) { + String k3 = i3.next(); + JSONObject property = properties.getJSONObject(k3); + handleParameter2(property); + handleXml(property); + } + } + handleXml(objectType); + removeEmptyList(objectType, "required"); + removeEmptyList(objectType, "allOf"); + } + } + // System.err.println(json.toString(2)); + + return json; + } + + private static void handleXml(JSONObject json) { + if (json.has("xml")) { + JSONObject xml = json.getJSONObject("xml"); + removeDefault(xml, "wrapped", "false"); + if (xml.has("wrapped")) + xml.put("wrapped", true); + } + } + + private static void handleParameter2(JSONObject parameter) { + parameter.remove("lastChanged"); + removeDefault(parameter, "required", "false"); + removeEmptyList(parameter, "allOf"); + if (parameter.has("$class") + && (parameter.getString("$class").endsWith("SwaggerSimpleObjectType") + || parameter.getString("$class").endsWith("SwaggerEnumObjectType") || parameter.getString( + "$class").endsWith("SwaggerReferenceObjectType"))) { + handleDefinition2(parameter); + return; + } + JSONObject type = parameter.getJSONObject("type"); + handleDefinition2(type); + parameter.remove("type"); + copy(type, parameter, "default"); + copy(type, parameter, "description"); + if (type.has("required") && type.getString("required").equals("true")) + parameter.put("required", true); + if (parameter.has("in") && parameter.getString("in").equals("body")) { + JSONObject schema = new JSONObject(); + if (type.has("items")) { + schema.put("type", "array"); + JSONObject ref = new JSONObject(); + schema.put("items", ref); + ref.put("$ref", type.getJSONObject("items").get("$ref")); + } else { + schema.put("$ref", type.get("$ref")); + } + parameter.put("schema", schema); + } else { + copy(type, parameter, "type"); + copy(type, parameter, "enum"); + move(type, parameter, "format"); + moveInt(type, parameter, "minimum"); + moveInt(type, parameter, "maximum"); + if (type.has("items")) { + parameter.put("type", "array"); + } + copy(type, parameter, "items"); + copy(type, parameter, "collectionFormat"); + } + if (parameter.has("additionalProperties")) { + handleDefinition2(parameter.getJSONObject("additionalProperties")); + } + removeEmptyList(parameter, "comsumes"); + removeEmptyList(parameter, "produces"); + parameter.remove("lastChanged"); + } + + private static void handleDefinition2(JSONObject definition) { + definition.remove("lastChanged"); + removeDefault(definition, "required", "false"); + if (definition.has("reference")) { + definition.put("$ref", "#" + definition.getJSONObject("reference").getString("$ref")); + definition.remove("reference"); + definition.remove("type"); + } + if (definition.getBoolean("many")) { + JSONObject items = new JSONObject(); + definition.put("items", items); + move(definition, items, "type"); + move(definition, items, "enum"); + move(definition, items, "default"); + move(definition, items, "$ref"); + move(definition, items, "format"); + move(definition, items, "minimum"); + move(definition, items, "maximum"); + definition.put("type", "array"); + } + removeDefault(definition, "collectionFormat", "csv"); + + definition.remove("many"); + definition.remove("$class"); + } + + private static void removeEmptyList(JSONObject json, String key) { + if (json.has(key) && json.getJSONArray(key).length() == 0) { + json.remove(key); + } + } + + private static void removeEmptyObject(JSONObject json, String key) { + if (json.has(key) && json.getJSONObject(key).length() == 0) { + json.remove(key); + } + } + + private static void removeDefault(JSONObject json, String key, Object value) { + if (json.has(key) && value.equals(json.get(key))) + json.remove(key); + } + + private static void convertFromObjectToArray(JSONObject res, String key, String name) { + JSONObject j = res.getJSONObject(key); + JSONArray a = new JSONArray(); + for (Iterator<String> i1 = j.keys(); i1.hasNext();) { + String k = i1.next(); + JSONObject j1 = new JSONObject(); + j1.put(name, k); + a.put(JsonUtils.merge(j1, j.getJSONObject(k))); + } + res.put(key, a); + } + + private static void copy(JSONObject from, JSONObject to, String key) { + if (from.has(key)) + to.put(key, from.get(key)); + } + + private static void move(JSONObject from, JSONObject to, String key) { + if (from.has(key)) { + to.put(key, from.get(key)); + from.remove(key); + } + } + + private static void moveInt(JSONObject from, JSONObject to, String key) { + if (from.has(key)) { + to.put(key, from.getInt(key)); + from.remove(key); + } + } + + @SuppressWarnings("unused") + private static void moveBoolean(JSONObject from, JSONObject to, String key) { + if (from.has(key)) { + to.put(key, from.getBoolean(key)); + from.remove(key); + } + } + + public static JSONObject server2json(ManagementServer s) { + try { + return swagger2json(server2swagger(s)); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("Unable to create Swagger object"); + } + + } + + private static SwaggerModel server2swagger(ManagementServer s) { + SwaggerModel m = SwaggerFactory.eINSTANCE.createSwaggerModel(); + try { + JSONObject json = new JSONObject(getTemplate("swagger-api.json")); + ManagementServer s1 = new ManagementServer(); + s1.setObject(SwaggerFactory.eINSTANCE.createSwaggerModel()); + m = json2swagger(s1, json); + } catch (Exception e) { + throw new RuntimeException("Unable to create initial Swagger object: " + e, e); + } + Map<String, Object> done = new HashMap<String, Object>(); + eclass2swagger("/resources", s.getObject().eClass(), m, done); + return m; + } + + static List<EClass> allEClasses = null; + + private static List<EClass> findSubClasses(EClass c) { + List<EClass> res = new ArrayList<EClass>(); + if (allEClasses == null) { + allEClasses = new ArrayList<EClass>(); + Registry i = EPackage.Registry.INSTANCE; + for (String x : i.keySet()) { + System.err.println("SWAGGER: " + x + " " + i.get(x)); + if (i.get(x) instanceof EPackage) { + EPackage p = (EPackage) i.get(x); + for (EClassifier c1 : p.getEClassifiers()) { + if (c1 instanceof EClass) { + EClass c2 = (EClass) c1; + allEClasses.add(c2); + } + } + } + } + } + for (EClass c1 : allEClasses) { + if (c.isSuperTypeOf(c1)) + res.add(c1); + } + return res; + } + + private static String getTemplate(String resource) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] data = new byte[65536]; + InputStream is = SwaggerUtils.class.getClassLoader().getResourceAsStream(resource); + if (is == null) { + throw new RuntimeException("Unable to find resource: " + resource); + } + int i; + try { + while ((i = is.read(data)) > 0) { + baos.write(data, 0, i); + } + } catch (Exception e) { + ManagementServerUtils.printStackTrace(e); + } finally { + if (is != null) + is.close(); + } + return (new String(baos.toByteArray())); + } + + private static void eclass2swagger(String path, EClass eClass, SwaggerModel m, Map<String, Object> done) { + String key = "eclass:" + eClass.getEPackage().getNsURI() + ":" + eClass.getName(); + System.err.println("SWAGGER: " + key + " " + path); + if (done.containsKey(key)) + return; + done.put(key, ""); + String tag = eclass2tag(eClass, m, done); + SwaggerPath p = SwaggerFactory.eINSTANCE.createSwaggerPath(); + p.setName(path); + m.getPaths().add(p); + p.getMethods().add(method("get", tag, "List object of type: " + eClass.getName())); + for (EReference ref : eClass.getEAllContainments()) { + for (EClass c1 : findSubClasses(ref.getEReferenceType())) { + eclass2swagger(path + "/" + ref.getName(), c1, m, done); + } + } + } + + public void autoAdd(String path, EClass eClass, int levels) { + autoAdd(path, eClass, levels, new ArrayList<String>()); + } + + public void autoAdd(String path, EClass eClass, int levels, List<String> pathVars) { + if (levels < 0) + return; + String key = "eclassAtPath:" + eClassName(eClass) + "@" + path; + if (done.containsKey(key)) + return; + // System.err.println("SWAGGER: " + key + " " + path); + done.put(key, ""); + String tag = path2tag(path); + SwaggerPath p = SwaggerFactory.eINSTANCE.createSwaggerPath(); + p.setName(path); + m.getPaths().add(p); + p.getMethods().add(listObjectMethod(tag, eClass, pathVars)); + p.getMethods().add(createObjectMethod(tag, eClass, pathVars)); + p.getMethods().add(updateObjectMethod(tag, eClass, pathVars)); + p.getMethods().add(deleteObjectMethod(tag, eClass, pathVars)); + for (EOperation op : eClass.getEAllOperations()) { + operationObjectMethod(path, tag, eClass, pathVars, op); + } + for (EReference ref : eClass.getEAllContainments()) { + addListObjectPath(path, pathVars, ref); + List<EClass> l = findSubClasses(ref.getEReferenceType()); + List<EClass> l2 = new ArrayList<EClass>(); + for (EClass c1 : l) { + String key2 = "eclass:recursion:" + tag + ":" + eClassName(eClass) + ":" + eClassName(c1); + if (done.containsKey(key2)) + continue; + done.put(key2, ""); + l2.add(c1); + } + int index = 0; + for (EClass c1 : l2) { + List<String> vars = new ArrayList<String>(); + vars.addAll(pathVars); + String v = pathVar(ref, l2, index++); + if (v.length() > 0) + vars.add(v.substring(2, v.length() - 1)); + autoAdd(path + "/" + ref.getName() + v, c1, levels - 1, vars); + } + } + // System.err.println("SWAGGER: DONE " + key + " " + path); + } + + private void addListObjectPath(String path, List<String> pathVars, EReference ref) { + if (!ref.isMany()) + return; + String path1 = path + "/" + ref.getName(); + String tag = path2tag(path1); + SwaggerPath p = SwaggerFactory.eINSTANCE.createSwaggerPath(); + p.setName(path1); + m.getPaths().add(p); + SwaggerOperation method = method("get", tag, "List " + ref.getName() + " names"); + addPathParameters(method, pathVars); + p.getMethods().add(method); + } + + private void addPathParameters(SwaggerOperation method, List<String> pathVars) { + for (String v : pathVars) { + addParameter(method, v, SwaggerParameterType.PATH, "string", null, null); + } + } + + private SwaggerOperation listObjectMethod(String tag, EClass c, List<String> pathVars) { + SwaggerOperation method = method("get", tag, "List object of type: " + c.getName()); + addPathParameters(method, pathVars); + addParameter(method, "levels", SwaggerParameterType.QUERY, "string", "1", "The number of levels return"); + return method; + } + + private SwaggerOperation createObjectMethod(String tag, EClass c, List<String> pathVars) { + SwaggerOperation method = method("post", tag, "Create new object of type: " + c.getName()); + addPathParameters(method, pathVars); + addBodyParameter(method, c); + return method; + } + + private void addBodyParameter(SwaggerOperation method, EClass c) { + SwaggerParameter p = SwaggerFactory.eINSTANCE.createSwaggerParameter(); + p.setName("body"); + p.setIn(SwaggerParameterType.BODY); + SwaggerReferenceObjectType type = SwaggerFactory.eINSTANCE.createSwaggerReferenceObjectType(); + type.setRequired(true); + type.setReference(findDefinition(c)); + p.setType(type); + type.setDescription("JSON representation of " + c.getName()); + method.getParameters().add(p); + } + + private SwaggerObjectClassDefinition findDefinition(EClass c) { + String key = "definition:" + eClassName(c); + if (done.containsKey(key)) + return (SwaggerObjectClassDefinition) done.get(key); + + SwaggerObjectClassDefinition res = SwaggerFactory.eINSTANCE.createSwaggerObjectClassDefinition(); + + res.setName(c.getName()); + for (EAttribute attr: c.getEAllAttributes()) { + SwaggerSimpleObjectType p = newSimpleType("string", attr.isRequired()); + // TODO fix more stuff here + p.setName(attr.getName()); + res.getProperties().add(p); + } + m.getDefinitions().add(res); + done.put(key,res); + return res ; + } + + private SwaggerObjectClassDefinition operationDefinition(EOperation op) { + SwaggerObjectClassDefinition res = SwaggerFactory.eINSTANCE.createSwaggerObjectClassDefinition(); + res.setName(op.getEContainingClass().getName() + "@" + op.getName()); + for (EParameter param: op.getEParameters()) { + SwaggerSimpleObjectType p = newSimpleType("string", param.isRequired()); + // TODO fix more stuff here + p.setName(param.getName()); + res.getProperties().add(p); + } + m.getDefinitions().add(res); + return res; + } + + private SwaggerOperation updateObjectMethod(String tag, EClass c, List<String> pathVars) { + SwaggerOperation method = method("put", tag, "Update existing object of type: " + c.getName()); + addPathParameters(method, pathVars); + addBodyParameter(method, c); + return method; + } + + private SwaggerOperation deleteObjectMethod(String tag, EClass c, List<String> pathVars) { + SwaggerOperation method = method("delete", tag, "Delete existing object of type: " + c.getName()); + addPathParameters(method, pathVars); + return method; + } + + private SwaggerOperation operationObjectMethod(String path, String tag, EClass c, List<String> pathVars, EOperation op) { + SwaggerOperation method = method("put", tag, "Delete existing object of type: " + c.getName()); + addParameter(method, "action", SwaggerParameterType.HEADER, "string", op.getName(), null); + addPathParameters(method, pathVars); + SwaggerPath p = SwaggerFactory.eINSTANCE.createSwaggerPath(); + p.setName(path + "/_ACTION/" + op.getName()); + m.getPaths().add(p); + p.getMethods().add(method); + + + // TODO this makes the toJson() crash. + SwaggerParameter parameter = SwaggerFactory.eINSTANCE.createSwaggerParameter(); + parameter.setName("body"); + parameter.setIn(SwaggerParameterType.BODY); + SwaggerReferenceObjectType type = SwaggerFactory.eINSTANCE.createSwaggerReferenceObjectType(); + type.setRequired(true); + type.setReference(operationDefinition(op)); + parameter.setType(type); + type.setDescription("JSON representation of " + c.getName()); + method.getParameters().add(parameter); + +// SwaggerObjectClassDefinition type = SwaggerFactory.eINSTANCE.createSwaggerObjectClassDefinition(); +// parameter.setType(type); +// type.setDescription("JSON representation of parameters to " + op.getName()); +// for (EParameter p1 : op.getEParameters()) { +// type.getProperties().add(eparam2property(p1)); +// } + + return method; + } + + @SuppressWarnings("unused") + private SwaggerNamedObjectType eparam2property(EParameter p1) { + SwaggerSimpleObjectType p = newSimpleType("string", p1.isRequired()); + return p; + } + + private static void addParameter(SwaggerOperation method, String name, SwaggerParameterType ptype, String type, + String def, String description) { + SwaggerParameter p = SwaggerFactory.eINSTANCE.createSwaggerParameter(); + p.setName(name); + p.setIn(ptype); + SwaggerSimpleObjectType stype = newSimpleType(type, def == null); + p.setType(stype); + stype.setDescription(description); + method.getParameters().add(p); + } + + private String pathVar(EReference ref, List<EClass> l, int index) { + String indexName = l.size() == 1 ? "" : Integer.toString(index); + if (!ref.isMany()) + return indexName.equals("") ? "" : "{" + indexName + "}"; + String name = ref.getName(); + if (name.endsWith("ies")) + name = name.substring(0, name.length() - 3) + "y"; + else if (name.endsWith("es")) + name = name.substring(0, name.length() - 2); + else if (name.endsWith("s")) + name = name.substring(0, name.length() - 1); + return "/{" + name + indexName + "}"; + } + + private String eClassName(EClass eClass) { + return eClass.getEPackage().getNsURI() + ":" + eClass.getName(); + } + + private String path2tag(String path) { + String res = null; + String tagName = path2tagName(path); + System.err.println("path=" + path + " tagName=" + tagName); + for (SwaggerTag tag : m.getTags()) { + if (!tagName.startsWith(tag.getName())) + continue; + if (res != null && tag.getName().length() < res.length()) + continue; + res = tag.getName(); + } + if (res == null) { + if (!rootTagAdded) { + rootTagAdded = true; + addTag("ROOT", "Anything else"); + } + res = "ROOT"; + } + return res; + } + + private String path2tagName(String path) { + // SWAGGER does not support / in tags + if (path.contains("/")) + return path.substring(1).replace("/", "-"); + return path; + } + + private static SwaggerOperation method(String name, String tag, String description) { + SwaggerOperation res = SwaggerFactory.eINSTANCE.createSwaggerOperation(); + res.setName(name); + res.setDescription(description); + res.getTags().add(tag); + // SwaggerParameter p = + // SwaggerFactory.eINSTANCE.createSwaggerParameter(); + // p.setName("Authorization"); + // p.setIn(SwaggerParameterType.HEADER); + // p.setType(newSimpleType("string",true)); + // res.getParameters().add(p); + addParameter(res, "Authorization", SwaggerParameterType.HEADER, "string", null, "Basic HTTP Authorization"); + addParameter(res, "X-ECOMP-RequestID", SwaggerParameterType.HEADER, "string", null, "ECOMP Request ID"); + return res; + } + + private static SwaggerSimpleObjectType newSimpleType(String type, boolean required) { + SwaggerSimpleObjectType res = SwaggerFactory.eINSTANCE.createSwaggerSimpleObjectType(); + res.setRequired(required); + res.setType(type); + return res; + } + + private static String eclass2tag(EClass eClass, SwaggerModel m, Map<String, Object> done) { + String key = "tag:" + eClass.getEPackage().getNsURI(); + if (done.containsKey(key)) + return (String) done.get(key); + SwaggerTag tag = SwaggerFactory.eINSTANCE.createSwaggerTag(); + tag.setName(eClass.getEPackage().getNsURI()); + m.getTags().add(tag); + done.put(key, tag.getName()); + return tag.getName(); + } + + public void autoAddApi(String path, EObject o) { + System.err.println("SWAGGER: autoAddApi " + path + " " + o + " \n"); + // Thread.dumpStack(); + if (alreadyDone("auto-add-api: " + path + " : " + o.hashCode())) + return; + if (o instanceof ISwaggerHandler) { + ISwaggerHandler handler = (ISwaggerHandler) o; + handler.updateSwagger(path, this); + } else + autoAdd(path, o.eClass(), 1000); + System.err.println("SWAGGER: autoAddApi DONE" + path + " " + o); + } + + /** + * Adds Swagger Tag to Model + * + * @param path + * The resource path that this tag represent + * @param description + * Tag Description + */ + public void addTag(String path, String description) { + String key = "tag:" + path; + if (done.containsKey(key)) + return; + SwaggerTag tag = SwaggerFactory.eINSTANCE.createSwaggerTag(); + tag.setName(path2tagName(path)); + tag.setDescription(description); + m.getTags().add(tag); + done.put(key, tag.getName()); + } + + public void addTag(String path, String description, EObject o) { + addTag(path, description); + autoAddApi(path, o); + } + + /** + * @return JSON representation of Swagger Model + */ + public JSONObject toJson() { + try { + return swagger2json(m); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("Unable to convert Swagger Model to Json: " + e); + } + } + + private boolean alreadyDone(String key) { + if (done.containsKey(key)) + return true; + System.err.println("SWAGGER: " + key); + done.put(key, ""); + return false; + } +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/logs/LogMessageManager.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/logs/LogMessageManager.java new file mode 100644 index 0000000..cd5798f --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/logs/LogMessageManager.java @@ -0,0 +1,285 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager.logs;
+
+import java.io.File;
+import java.util.Date;
+import java.util.HashMap;
+
+import org.apache.log4j.Logger;
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EObject;
+
+import org.openecomp.ncomp.core.logs.*;
+import org.openecomp.ncomp.sirius.function.FunctionUtils;
+import org.openecomp.ncomp.sirius.manager.*;
+import org.openecomp.ncomp.utils.journaling.JournalingList;
+
+public class LogMessageManager {
+ public static final Logger logger = Logger.getLogger(LogMessageManager.class);
+ public static final Logger logger2 = Logger.getLogger("org.openecomp.ncomp.sirius.manager.uploaded");
+ private HashMap<String, LogMessageStore> logs = new HashMap<String, LogMessageStore>();
+ private JournalingList<String> allLogs = null;
+ private ManagementServer s;
+
+ public LogMessageManager(ManagementServer s) {
+ super();
+ this.s = s;
+ }
+
+ public synchronized void addLogMessage(EObject o, Message m) {
+ o2logs(o).add(m);
+ }
+
+ public synchronized void addLogMessage(EObject o, LogMessage m) {
+ Message m1 = new Message(m);
+ addLogMessage(o, m1);
+ }
+
+ public synchronized EList<LogMessage> getMessages(EObject o, Date start, Date end) {
+ return o2logs(o).getMessages(start, end);
+ }
+
+ private LogMessageStore o2logs(EObject o) {
+ return path2logs(ManagementServer.object2ref(o));
+ }
+
+ private LogMessageStore path2logs(String path) {
+ initLogs();
+ LogMessageStore store = logs.get(path);
+ if (store == null) {
+ String dir = s.getProps().getProperty("logs.dir", "data/logs") + path;
+ store = new LogMessageStore(dir, path);
+ logs.put(path, store);
+ if (!allLogs.contains(path)) {
+ allLogs.add(path);
+ allLogs.save();
+ }
+ }
+ return store;
+ }
+
+ @SuppressWarnings("unchecked")
+ private void initLogs() {
+ if (allLogs == null) {
+ String file = s.getProps().getProperty("logs.dir", "data/logs") + "/allLogs.dat";
+ allLogs = JournalingList.create(new File(file));
+ }
+ }
+
+ public synchronized EList<LogMessage> getMessages(String prefixPath, Date start, Date end) {
+ EList<LogMessage> res = new BasicEList<LogMessage>();
+ initLogs();
+ for (String p : allLogs) {
+ // TODO THIS DOES NOT WORK
+ // if (!p.startsWith(prefixPath))
+ // continue;
+ for (LogMessage m : path2logs(p).getMessages(start, end)) {
+ if (m.getResourceName().startsWith(prefixPath))
+ res.add(m);
+ }
+ }
+ return LogMessageStore.sortMessages(res);
+ }
+
+ public synchronized void save() {
+ for (LogMessageStore s : logs.values())
+ s.logs.save();
+ }
+
+ public void updateLogs(EObject s, EList<LogMessage> logs, EList<LogMessageRule> rules, Logger logger) {
+ String path = ManagementServer.object2ref(s);
+ for (LogMessage log : logs) {
+ if (log.getTime() < 140646778200L) {
+ logger.warn("Metric time is too old:" + new Date(log.getTime()));
+ log.setTime(new Date().getTime());
+ }
+ // System.err.println "new log $log $path"
+ if (log.getResourceName() == null) {
+ log.setResourceName(path);
+ } else {
+ if (log.getResourceName().startsWith("/")) {
+ log.setResourceName(path + log.getResourceName());
+ } else {
+ log.setResourceName(path + "/" + log.getResourceName());
+ }
+ }
+// if (log.getCategory() == null) {
+// setCategory(log);
+// }
+ updateLogMessage(log, rules);
+ String m = "resource=" + log.getResourceName() + " severity=" + log.getSeverity() + " " + log.getMessage();
+ updateServer(log);
+ switch (log.getLevel()) {
+ case INFO:
+ logger2.info(m);
+ break;
+ case WARN:
+ logger2.warn(m);
+ break;
+ case ERROR:
+ logger2.error(m);
+ break;
+ case FATAL:
+ logger2.fatal(m);
+ break;
+ default:
+ break;
+ }
+ addLogMessage(s, log);
+ }
+ save(60000L); // save every minute
+ }
+
+ private void updateServer(LogMessage log) {
+ LogMessageContainer o = findLogContainer(log);
+ if (o == null) return;
+ updateLogStatsContainer(o,log);
+ }
+
+ private LogMessageContainer findLogContainer(LogMessage log) {
+ Subject subject = ManagementServer.find(s.getObject(), log.getResourceName(), true);
+ LogMessageContainer c = null;
+ if (subject != null && subject.o != null) {
+ EObject oo = subject.o;
+ while (oo != null) {
+ if (oo instanceof LogMessageContainer) {
+ c = (LogMessageContainer) oo;
+ break;
+ }
+ oo = oo.eContainer();
+ }
+ }
+ if (c == null) {
+ logger.warn("unable to find LogMessageContainer for: " + log.getResourceName());
+ return null;
+ }
+ return c;
+ }
+
+ private LogMessageCategory findLogCategory(String name, LogMessage log) {
+ LogMessageContainer c = findLogContainer(log);
+ if (c == null) return null;
+ LogMessageCategory cat = null;
+ for (LogMessageCategory cat1 : c.getLogMessageCategories()) {
+ if (cat1.getName().equals(name)) {
+ cat = cat1;
+ break;
+ }
+ }
+ if (cat == null) {
+ cat = LogsFactory.eINSTANCE.createLogMessageCategory();
+ cat.setName(name);
+ c.getLogMessageCategories().add(cat);
+ }
+ return cat;
+ }
+
+ private void updateLogStatsContainer(EObject o, LogMessage log) {
+ if (o instanceof LogMessageContainer) {
+ LogMessageContainer c = (LogMessageContainer) o;
+ updateLogStats(c.getLogMessageStats(),log.getSeverity().toString(),log.getSeverity(),null,LogSeverity.UNKNOWN);
+ updateLogStats(c.getLogMessageStats(),"ALL",null,null,LogSeverity.UNKNOWN);
+ }
+ if (o.eContainer() != null)
+ updateLogStatsContainer(o.eContainer(), log);
+ }
+
+ private void updateLogStats(EList<LogMessageStats> l, String n, LogSeverity sev, LogLevel level, LogSeverity minLogSeverity) {
+ if (minLogSeverity != null && minLogSeverity != LogSeverity.UNKNOWN && (sev == null || sev == LogSeverity.UNKNOWN || sev.ordinal() > minLogSeverity.ordinal())) return;
+ LogMessageStats stats = (LogMessageStats) ManagementServer.findInNamedList(l, n);
+ if (stats == null) {
+ stats = LogsFactory.eINSTANCE.createLogMessageStats();
+ stats.setName(n);
+ stats.setLevel(level);
+ stats.setSeverity(sev);
+ l.add(stats);
+ }
+ if (stats.getCount() == null)
+ s.metrics.initAttribute(stats,"count");
+ if (stats.getCount() != null)
+ stats.getCount().increase(1L,false);
+ }
+
+ @SuppressWarnings("unused")
+ private void setCategory(LogMessage log) {
+ log.setCategory(log.getMessage().replaceAll("Exchange@[0-9a-f]+", "EEE").replaceAll("[0-9]+", "NNN"));
+ }
+
+ long lastUpdate = 0;
+
+ private void save(long i) {
+ long now = new Date().getTime();
+ if (lastUpdate + i < now) {
+ save();
+ lastUpdate = new Date().getTime();
+ }
+
+ }
+
+ private void updateLogMessage(LogMessage log, EList<LogMessageRule> rules) {
+ if (rules == null)
+ return;
+ logger.debug("Log:" + log);
+ for (LogMessageRule r : rules) {
+ logger.debug("Rule:" + r);
+ if (r.isDisabled())
+ continue;
+ try {
+ if (r.getMessageFilter() != null && !log.getMessage().matches(r.getMessageFilter()))
+ continue;
+ if (r.getResourcePathFilter() != null && !log.getResourceName().matches(r.getResourcePathFilter()))
+ continue;
+ } catch (Exception e) {
+ r.setDisabled(true);
+ logger.error("error in log message rule (now disabled): " + e);
+ }
+ if (r.getLevel() != LogLevel.UNKNOWN && log.getLevel() != r.getLevel())
+ continue;
+ if (r.getSeverity() != LogSeverity.UNKNOWN && log.getSeverity() != r.getSeverity())
+ continue;
+ LogMessageCategory cat = findLogCategory(r.getName(), log);
+ if (r.getNewLevel() != LogLevel.UNKNOWN)
+ log.setLevel(r.getNewLevel());
+ if (r.getNewSeverity() != LogSeverity.UNKNOWN)
+ log.setSeverity(r.getNewSeverity());
+ updateLogStats(cat.getStats(),"ALL",null,null,null);
+ if (r.getUpdateFunction() != null) {
+// System.err.println("XYZ : " + log + " " + r.getUpdateFunction() + " " + findLogCategory(r.getName(),log));
+ LogMessageState logState = LogsFactory.eINSTANCE.createLogMessageState();
+ logState.setLog(log);
+ logState.setCategory(cat);
+ logState.setSuspended(ManagementServer.isSuspended(cat, null));
+ FunctionUtils.update(logState, r.getUpdateFunction(), false);
+// System.err.println("XYZ : " + log);
+ }
+ logger.debug("Rule matched:" + r);
+ String n = log.getSeverity().toString() + ":" + log.getLevel().toString();
+ updateLogStats(cat.getStats(),n,log.getSeverity(),log.getLevel(),LogSeverity.SEV3);
+ // should break but SOMF does not handle list order correctly.
+ // Note SOMF does now handle order.
+ }
+ }
+
+}
diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/logs/LogMessageStore.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/logs/LogMessageStore.java new file mode 100644 index 0000000..2d1c10d --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/logs/LogMessageStore.java @@ -0,0 +1,73 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager.logs;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+
+import org.openecomp.ncomp.core.logs.LogMessage;
+import org.openecomp.ncomp.utils.SortUtil;
+import org.openecomp.ncomp.utils.journaling.JournalingDateObject;
+import org.openecomp.ncomp.utils.journaling.JournalingList;
+import org.openecomp.ncomp.webservice.utils.DateUtils;
+
+public class LogMessageStore {
+
+ JournalingDateObject<JournalingList<Message>> logs;
+ public LogMessageStore(String dir, String path) {
+ logs = new JournalingDateObject<JournalingList<Message>>(dir, JournalingList.class);
+ }
+
+ public void add(Message m) {
+ logs.get(m.time).add(m);
+ }
+
+ public EList<LogMessage> getMessages(Date start, Date end) {
+ List<LogMessage> res = new ArrayList<LogMessage>();
+ for (Date d: DateUtils.dateRange(start, end, DateUtils.stringToDuration("1day"))) {
+ for (Message m : logs.get(d)) {
+ if (m.time.before(start) || m.time.after(end)) continue;
+ res.add(m.toLogMessage());
+ }
+ }
+ return sortMessages(res);
+ }
+
+ public static EList<LogMessage>sortMessages(Collection<LogMessage> l) {
+ return new BasicEList<LogMessage>(SortUtil.sort(l, comp));
+ }
+
+ private static Comparator<? super LogMessage> comp = new Comparator<LogMessage>() {
+ @Override
+ public int compare(LogMessage t1, LogMessage t2) {
+ return - ((Long)t1.getTime()).compareTo(t2.getTime());
+ }
+ };
+
+
+}
diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/logs/LogMessageSuppressor.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/logs/LogMessageSuppressor.java new file mode 100644 index 0000000..80c7eb9 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/logs/LogMessageSuppressor.java @@ -0,0 +1,109 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager.logs;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+
+import org.openecomp.ncomp.core.logs.LogMessage;
+import org.openecomp.ncomp.sirius.manager.ManagementServerUtils;
+
+public class LogMessageSuppressor {
+
+ public interface ILogMessageHandler {
+ void handleLog(LogMessage m);
+ }
+
+ private ILogMessageHandler handler;
+
+ class LogMessageContainer {
+ public LogMessageContainer(LogMessage m) {
+ this.m = m;
+ d = new Date();
+ }
+
+ Date d;
+ LogMessage m;
+ int num = 0;
+ }
+
+ public LogMessageSuppressor(ILogMessageHandler handler1, long duration1) {
+ super();
+ this.duration = duration1;
+ this.handler = handler1;
+ Thread t = new Thread("log message suppressor") {
+ @Override
+ public void run() {
+ while (true) {
+ try {
+ Thread.sleep(30000);
+ synchronized (LogMessageSuppressor.this) {
+ long now = new Date().getTime();
+ List<String> remove = new ArrayList<String>();
+ for (String k : map.keySet()) {
+ LogMessageContainer c = map.get(k);
+ if (c.d.getTime() + duration < now) {
+ remove.add(k);
+ }
+ }
+ for (String k : remove) {
+ LogMessageContainer c = map.remove(k);
+ if (c.num > 1) {
+ c.m.setMessage(c.m.getMessage() + " Suppressed messages: " + c.num + " in last " + duration / 1000
+ + " seconds");
+ handler.handleLog(c.m);
+ }
+ }
+ }
+ } catch (Exception e) {
+ ManagementServerUtils.printStackTrace(e);
+ }
+ }
+ }
+ };
+ t.start();
+ }
+
+ long duration;
+ HashMap<String, LogMessageContainer> map = new HashMap<String, LogMessageContainer>();
+
+ public synchronized void add(LogMessage m) {
+ String k = messageKey(m);
+ LogMessageContainer d = map.get(k);
+ if (d == null) {
+ handler.handleLog(m);
+ d = new LogMessageContainer(m);
+ map.put(k, d);
+ }
+ d.num ++;
+ }
+
+ private String messageKey(LogMessage m) {
+ String k = m.getResourceName() + ":" + m.getLevel().toString() + ":" + (m.getTime() / duration) + ":"
+ + m.getMessage().replaceAll("Exchange@[0-9a-f]+", "EEE").replaceAll("[0-9]+", "NNN");
+ // System.out.println(m.getMessage() + " -> " + k);
+ return k;
+ }
+
+}
diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/logs/LogScanner.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/logs/LogScanner.java new file mode 100644 index 0000000..ff30a9a --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/logs/LogScanner.java @@ -0,0 +1,104 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager.logs;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+
+import org.openecomp.ncomp.core.logs.LogConfiguration;
+import org.openecomp.ncomp.core.logs.LogFile;
+import org.openecomp.ncomp.core.logs.LogPattern;
+import org.openecomp.ncomp.utils.StringMatcher;
+import org.openecomp.ncomp.utils.StringUtil;
+import org.openecomp.ncomp.utils.extra.FileTail.NewLineHandler;
+
+public class LogScanner implements NewLineHandler {
+ interface LogMessageHandler {
+ void newLog(Message msg);
+ void fixFilePermissions(File file);
+ }
+
+ private LogMessageHandler handler;
+ private LogConfiguration config;
+ private String directory;
+
+ public LogScanner(LogMessageHandler handler, LogConfiguration config, String directory) {
+ this.handler = handler;
+ this.config = config;
+ this.directory = directory;
+ init();
+ }
+
+ private void init() {
+ for (LogFile f : config.getFiles()) {
+ List<PatternUtility> l = new ArrayList<LogScanner.PatternUtility>();
+ for (LogPattern p : f.getPatterns()) {
+ PatternUtility m = new PatternUtility();
+ m.f = f;
+ m.p = p;
+ m.m = new StringMatcher(p.getPattern());
+ l.add(m);
+ }
+ new org.openecomp.ncomp.utils.extra.FileTail(f.getFilename(), directory, null, null, null, this, l);
+ }
+
+ }
+
+ @Override
+ public void newLine(String file, String line, Object context) {
+ @SuppressWarnings("unchecked")
+ List<PatternUtility> l = (List<PatternUtility>) context;
+ HashMap<String, String> h = new HashMap<String, String>();
+ Date date = new Date();
+ for (PatternUtility m : l) {
+ if (m.m.match(line, h, date)) {
+ String level = expand(m.p.getLevel(), "${level}", h);
+ String severity = expand(m.p.getSeverity(), "${severity}", h);
+ String message = expand(m.p.getMessage(), "${message}", h);
+ String path = expand(m.p.getPath(), "${message}", h);
+ Message msg = new Message(level, severity, message, path, date);
+ handler.newLog(msg);
+ }
+ }
+
+ }
+
+ private String expand(String str, String def, HashMap<String, String> h) {
+ if (str == null) str = def;
+ return StringUtil.expandUsingMap(str, h, "$");
+ }
+
+ private class PatternUtility {
+ StringMatcher m;
+ LogFile f;
+ LogPattern p;
+ }
+
+ @Override
+ public void fixFilePermissions(File file) {
+ handler.fixFilePermissions(file);
+ }
+
+}
diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/logs/Message.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/logs/Message.java new file mode 100644 index 0000000..a4e3586 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/logs/Message.java @@ -0,0 +1,102 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager.logs;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import org.openecomp.ncomp.core.logs.LogLevel;
+import org.openecomp.ncomp.core.logs.LogMessage;
+import org.openecomp.ncomp.core.logs.LogSeverity;
+import org.openecomp.ncomp.core.logs.LogsFactory;
+
+public class Message implements Serializable {
+ @Override
+ public String toString() {
+ return "Message [level=" + level + ", severity=" + severity + ", message=" + message + ", path=" + path + ", time=" + time
+ + ", creationTime=" + creationTime + "]";
+ }
+ private static final long serialVersionUID = 1L;
+ public Message(){}
+ public Message(LogLevel level, LogSeverity severity, String message, Date time) {
+ super();
+ this.level = level;
+ this.severity = severity;
+ this.message = message;
+ this.time = time;
+ creationTime = new Date();
+ }
+ public Message(LogMessage m) {
+ level = m.getLevel();
+ severity = m.getSeverity();
+ message = m.getMessage();
+ time = new Date(m.getTime());
+ path = m.getResourceName();
+ creationTime = new Date();
+ }
+ public Message(String level2, String severity2, String message2, String path2, Date time) {
+ level = LogLevel.valueOf(level2);
+ severity = LogSeverity.valueOf(severity2);
+ this.message = message2;
+ this.path = path2;
+ this.time = time;
+ creationTime = new Date();
+ }
+ private LogLevel level;
+ private LogSeverity severity;
+ private String message;
+ private String path;
+ Date time;
+ private Date creationTime;
+
+ public LogLevel getLevel() {
+ return level;
+ }
+
+ public LogSeverity getSeverity() {
+ return severity;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+ public String getPath() {
+ return path;
+ }
+ public Date getTime() {
+ return time;
+ }
+
+ public Date getCreationTime() {
+ return creationTime;
+ }
+
+ public LogMessage toLogMessage() {
+ LogMessage m = LogsFactory.eINSTANCE.createLogMessage();
+ m.setLevel(level);
+ m.setSeverity(severity);
+ m.setMessage(message);
+ m.setResourceName(path);
+ m.setTime(time.getTime());
+ return m;
+ }
+}
diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/metrics/MetricManager.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/metrics/MetricManager.java new file mode 100644 index 0000000..1ca5e7f --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/metrics/MetricManager.java @@ -0,0 +1,605 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager.metrics;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.log4j.Logger;
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EAnnotation;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import org.openecomp.ncomp.component.Api;
+import org.openecomp.ncomp.core.metrics.AggregationMetricValueOption;
+import org.openecomp.ncomp.core.metrics.AggregationMetricValueOptionType;
+import org.openecomp.ncomp.core.metrics.BasicMetricValueOption;
+import org.openecomp.ncomp.core.metrics.MetricValueOption;
+import org.openecomp.ncomp.core.metrics.MetricsFactory;
+import org.openecomp.ncomp.core.metrics.SequenceMetricValueOption;
+import org.openecomp.ncomp.core.types.metrics.DateMetricAttribute;
+import org.openecomp.ncomp.core.types.metrics.DoubleMetricAttribute;
+import org.openecomp.ncomp.core.types.metrics.DoubleMetricMeasurement;
+import org.openecomp.ncomp.core.types.metrics.IncreasingULongMetricAttribute;
+import org.openecomp.ncomp.core.types.metrics.LongMetricAttribute;
+import org.openecomp.ncomp.core.types.metrics.MetricAttribute;
+import org.openecomp.ncomp.core.metrics.DoubleMetric;
+import org.openecomp.ncomp.core.metrics.LongMetric;
+import org.openecomp.ncomp.core.metrics.Metric;
+import org.openecomp.ncomp.sirius.manager.*;
+import org.openecomp.ncomp.utils.SortUtil;
+import org.openecomp.ncomp.utils.StringUtil;
+import org.openecomp.ncomp.utils.journaling.JournalingList;
+import org.openecomp.ncomp.webservice.utils.DateUtils;
+
+public class MetricManager {
+ public static final Logger logger = Logger.getLogger(MetricManager.class);
+ ManagementServer server;
+ private HashMap<String, MetricStore> path2store = new HashMap<String, MetricStore>();
+ private JournalingList<String> allStores = null;
+
+ @SuppressWarnings("unchecked")
+ public MetricManager(ManagementServer s) {
+ super();
+ this.server = s;
+ String dir = s.getProps().getProperty("metrics.dir");
+ if (dir == null)
+ return;
+ String file = dir + "/allStores.dat";
+ allStores = JournalingList.create(new File(file));
+ // TODO initialize old stores in separate thread.
+ initManager();
+ }
+
+ private void initManager() {
+ final Thread t = new Thread("init metrics") {
+ @Override
+ public void run() {
+ while (server.getObject() == null) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ ManagementServerUtils.printStackTrace(e);
+ }
+ }
+ logger.info("Starting initializing Metric Stores");
+ List<String> l = new ArrayList<String>(allStores);
+ for (String path : l) {
+ Subject s = ManagementServer.find(server.getObject(), "/" + path);
+ if (s == null || s.o == null) {
+ continue;
+ }
+ MetricStore store = getStore(s.o);
+ store.initStore();
+ }
+ logger.info("Done initializing Metric Stores");
+ }
+ };
+ t.start();
+ Thread t1 = new Thread("record metrics") {
+ @Override
+ public void run() {
+ // wait for initialization to complete before starting to record
+ try {
+ t.join();
+ } catch (InterruptedException e1) {
+ logger.warn("Failure while waiting for thread initialization to complete: " + e1);
+ }
+ while (true) {
+ try {
+ Thread.sleep(60000);
+ updateMetrics(server.getObject());
+ } catch (Exception e) {
+ logger.warn("recording metrics " + e);
+ e.printStackTrace();
+ }
+ }
+ }
+
+ };
+ t1.start();
+ }
+ private void updateMetrics(EObject o) {
+ for (EAttribute attr : o.eClass().getEAllAttributes()) {
+ Object a = o.eGet(attr);
+ if (a instanceof MetricAttribute) {
+ MetricAttribute m = (MetricAttribute) a;
+ m.record();
+ }
+ }
+ for (EReference ref : o.eClass().getEAllContainments()) {
+ if (ref.isMany()) {
+ @SuppressWarnings("unchecked")
+ EList<EObject> l = (EList<EObject>) o.eGet(ref);
+ for (EObject o1 : l) {
+ updateMetrics(o1);
+ }
+ }
+ else {
+ EObject o1 = (EObject) o.eGet(ref);
+ if (o1 != null) updateMetrics(o1);
+ }
+ }
+
+ }
+
+ public MetricStore getStore(EObject o) {
+ String path = ManagementServer.object2ref(o);
+ MetricStore store = path2store.get(path);
+ if (store == null) {
+ // path2metric[cc] = [:]
+ String dir = server.getProps().getProperty("metrics.dir", "data/metrics");
+ store = new MetricStore(dir + path, o, this);
+ path2store.put(path, store);
+ if (!allStores.contains(path)) {
+ allStores.add(path);
+ allStores.save();
+ }
+ }
+ return store;
+ }
+
+ public void updateMetric(EObject o, EAttribute attr, Object value) {
+ MetricStore store = findStore(o);
+ String path = ManagementServer.relativeObject2ref(store.getObject(), o);
+ if (path == null) {
+ System.err.println("Internal error in findStore (null path): " + store.getObject() + " " + o);
+ System.err.println(store.getObject().eContainer() + " " + o.eContainer());
+ System.err.println(ManagementServer.object2ref(store.getObject()) + " " + ManagementServer.object2ref(o));
+ return;
+ // throw new
+ // RuntimeException("Internal error in findStore (null path): " +
+ // store.getObject() + " " + o);
+ }
+ path = path + "/" + attr.getName();
+ String t = attr.getEType().getName();
+ // System.err.println("adding " + path + " " + t + " " + value);
+ if (t.equals("IncreasingULongMetricAttribute")) {
+ store.addLongValue(path, new Date(), value2long(value), t, false);
+ } else if (t.equals("LongMetricAttribute")) {
+ store.addLongValue(path, new Date(), value2long(value), t, false);
+ } else if (t.equals("DoubleMetricAttribute")) {
+ store.addDoubleValue(path, new Date(), value2double(value), t);
+ } else if (t.equals("DateMetricAttribute")) {
+ store.addLongValue(path, new Date(), value2long(value), t, false);
+ } else if (t.equals("StringMetricAttribute")) {
+ logger.warn("Unsuppported metric: " + t);
+ }
+ }
+
+ private Double value2double(Object value) {
+ if (value instanceof Double) {
+ return (Double) value;
+ }
+ if (value instanceof Integer) {
+ Integer i = (Integer) value;
+ return i.doubleValue();
+ }
+ if (value instanceof Long) {
+ Long i = (Long) value;
+ return i.doubleValue();
+ }
+ if (value instanceof String) {
+ return Double.parseDouble((String) value);
+ }
+ throw new RuntimeException("Unable to convert value to double: " + value + " " + value.getClass());
+ }
+
+ private long value2long(Object value) {
+ if (value instanceof Long) {
+ return (Long) value;
+ }
+ if (value instanceof Integer) {
+ Integer i = (Integer) value;
+ return i.longValue();
+ }
+ if (value instanceof String) {
+ return Long.parseLong((String) value);
+ }
+ throw new RuntimeException("Unable to convert value to long: " + value + " " + value.getClass());
+ }
+
+ private MetricStore findStore(EObject o) {
+ if (o.eContainer() == null)
+ return getStore(o);
+ EAnnotation anno = o.eClass().getEAnnotation("http://openecomp.org/sirius/store");
+ if (anno != null)
+ return getStore(o);
+ return findStore(o.eContainer());
+ }
+
+ public void updateMetrics(EObject s, EList<Metric> metrics) {
+ MetricStore store = getStore(s);
+ for (Metric m : metrics) {
+ if (m.getTime() < 140646778200L) {
+ logger.warn("Metric time is too old:" + new Date(m.getTime()));
+ m.setTime(new Date().getTime());
+ }
+ try {
+ String x = m.getResourceName() + "/" + m.getMetricName();
+ // if (x.contains("qfsFilesystems")) System.err.println("ZZZ: "
+ // + x + " " + m);
+ if (m instanceof DoubleMetric) {
+ DoubleMetric dm = (DoubleMetric) m;
+ store.addDoubleValue(x, new Date(m.getTime()), dm.getValue(), null);
+ continue;
+ }
+ if (m instanceof LongMetric) {
+ LongMetric lm = (LongMetric) m;
+ store.addLongValue(x, new Date(m.getTime()), lm.getValue(), null, lm.isDelta());
+ continue;
+ }
+ logger.warn("unknown metric: " + m);
+ } catch (Exception e) {
+ logger.warn("unable to update metric " + m + " " + e);
+ ManagementServerUtils.printStackTrace(e);
+ }
+ }
+ store.save(30000);
+ }
+
+ public EList<DoubleMetric> getValues(String path, Long start, Long end, MetricValueOption option, boolean relativeInterval) {
+ return getValues(server.getObject(), start, end, path, option, relativeInterval);
+ }
+
+ public static EList<DoubleMetric> getValues(EObject o, Long start, Long end, String path, MetricValueOption option,
+ boolean relativeInterval) {
+ Subject s = ManagementServer.find(o, path);
+ if (s == null || s.o == null || s.attr == null)
+ throw new RuntimeException("Bad Path: " + path + " " + o);
+ if (start == null)
+ throw new RuntimeException("No start parameter");
+ if (end == null)
+ throw new RuntimeException("No end parameter");
+ Object a = s.o.eGet(s.attr);
+ if (!(a instanceof MetricAttribute)) {
+ if (a == null)
+ throw new RuntimeException("Null Attribute: " + s.o.eClass().getName() + "@" + s.attr.getName());
+ else
+ throw new RuntimeException("Not a metric Attribute: " + s.o.eClass().getName() + "@" + s.attr.getName());
+ }
+ return getValues((MetricAttribute) a, s.attr, start, end, ManagementServer.object2ref(o) + path, option, false);
+ }
+
+ public static double getValue(EObject o, String path, MetricValueOption option) {
+ Subject s = ManagementServer.find(o, path);
+ if (s == null || s.attr == null)
+ throw new RuntimeException("Bad Path: " + path);
+ Object a = s.o.eGet(s.attr);
+ if (!(a instanceof MetricAttribute)) {
+ throw new RuntimeException("Not a metric Attribute: " + s.o.eClass().getName() + "@" + s.attr.getName());
+ }
+ long d = option2duration(option);
+ MetricAttribute aa = (MetricAttribute) a;
+ if (d > 0) {
+ long end = new Date().getTime();
+ long start = end - d;
+ EList<DoubleMetric> l = getValues(aa, s.attr, start, end, path, option, true);
+ if (l.size() > 1) {
+ System.err.println("wrong number returned" + l);
+ return -3;
+ }
+ return l.size() == 1 ? l.get(0).getValue() : 0.0;
+ }
+ // TODO the value should depend on the options. E.g., date.
+ return getValue(aa);
+ }
+
+ private static double getValue(MetricAttribute aa) {
+ if (aa instanceof LongMetricAttribute) {
+ LongMetricAttribute m = (LongMetricAttribute) aa;
+ Long l = m.getValue();
+ return l == null ? null : l.doubleValue();
+ }
+ if (aa instanceof IncreasingULongMetricAttribute) {
+ IncreasingULongMetricAttribute m = (IncreasingULongMetricAttribute) aa;
+ return m.getValue();
+ }
+ if (aa instanceof DoubleMetricAttribute) {
+ DoubleMetricAttribute m = (DoubleMetricAttribute) aa;
+ return m.getValue();
+ }
+ return -1;
+ }
+
+ private static long option2duration(MetricValueOption option) {
+ if (option instanceof AggregationMetricValueOption) {
+ return DateUtils.stringToDuration(((AggregationMetricValueOption) option).getDuration());
+ }
+ if (option instanceof SequenceMetricValueOption) {
+ SequenceMetricValueOption o = (SequenceMetricValueOption) option;
+ long l = 0;
+ for (MetricValueOption o1 : o.getOptions()) {
+ long l1 = option2duration(o1);
+ if (l1 > l)
+ l = l1;
+ }
+ return l;
+ }
+ return 0;
+ }
+
+ private static EList<DoubleMetric> getValues(MetricAttribute a, EAttribute attr, Long start, Long end, String path,
+ MetricValueOption option, boolean relativeInterval) {
+ List<DoubleMetricMeasurement> ll = a.getValuesDouble(new Date(start), new Date(end));
+ EList<DoubleMetric> l = new BasicEList<DoubleMetric>();
+ for (DoubleMetricMeasurement v : ll) {
+ DoubleMetric m = MetricsFactory.eINSTANCE.createDoubleMetric();
+ m.setMetricName(attr.getName());
+ m.setValue(v.v);
+ m.setTime(v.d.getTime());
+ m.setResourceName(path);
+ l.add(m);
+ }
+// System.err.println("getValues path=" + path + " start=" + start + " end=" + end + " #values=" + l.size());
+ return handleOption(path, attr, l, start, end, option, relativeInterval);
+ }
+
+ private static EList<DoubleMetric> handleOption(String path, EAttribute attr, EList<DoubleMetric> values, Long start, Long end,
+ MetricValueOption option, boolean relativeInterval) {
+ if (option instanceof AggregationMetricValueOption) {
+ return handleOptionAggregation(path, attr, values, start, end, (AggregationMetricValueOption) option, relativeInterval);
+ }
+ if (option instanceof BasicMetricValueOption) {
+ return handleOptionBasic(attr, values, (BasicMetricValueOption) option);
+ }
+ if (option instanceof SequenceMetricValueOption) {
+ return handleOptionSequence(path, attr, values, start, end, (SequenceMetricValueOption) option, relativeInterval);
+ }
+ return values;
+ }
+
+ private static EList<DoubleMetric> handleOptionSequence(String path, EAttribute attr, EList<DoubleMetric> values, Long start, Long end,
+ SequenceMetricValueOption option, boolean relativeInterval) {
+ // System.err.println("handleOptionSequence:" + path + " " +
+ // attr.getName());
+ for (MetricValueOption o : option.getOptions()) {
+ values = handleOption(path, attr, values, start, end, o, relativeInterval);
+ }
+ return values;
+ }
+
+ private static EList<DoubleMetric> handleOptionBasic(EAttribute attr, EList<DoubleMetric> values, BasicMetricValueOption option) {
+ boolean isDate = attr.getEType().getName().equals("DateMetricAttribute");
+ // TODO handle date metrics when the value should be the difference
+ // between the current and prev time.
+ // EAnnotation anno =
+ // attr.getEAnnotation("http://openecomp.org/sirius/metric");
+ // anno.getDetails().get("type");
+ // System.err.println("handleOptionBasic:" + attr.getName() + " " +
+ // isDate);
+ for (DoubleMetric d : values) {
+ if (isDate)
+ d.setValue(d.getTime() - d.getValue());
+ }
+ return values;
+ }
+
+ private static EList<DoubleMetric> handleOptionAggregation(String path, EAttribute attr, EList<DoubleMetric> values, Long start,
+ Long end, AggregationMetricValueOption option, boolean relativeInterval) {
+ HashMap<Long, List<DoubleMetric>> m = new HashMap<Long, List<DoubleMetric>>();
+ // System.err.println("handleOptionAggregation:" + path + " " +
+ // attr.getName());
+ if (option.getDuration() == null || option.getDuration().equals(""))
+ return values;
+ long duration2 = DateUtils.stringToDuration(option.getDuration());
+ if (duration2 == 0)
+ return values;
+ if (!relativeInterval) {
+ start = start / duration2 * duration2;
+ end = end / duration2 * duration2 + duration2;
+ }
+ if (start > end)
+ throw new RuntimeException("Bad time interval");
+ long delta = start - (start / duration2 * duration2);
+ for (long t = start; t < end; t += duration2) {
+ m.put(t - delta, new ArrayList<DoubleMetric>());
+ // System.err.println("times " + (t - delta) + " " + new
+ // Date(t-delta));
+ }
+ for (DoubleMetric d : values) {
+ long tt = (d.getTime() - delta) / duration2 * duration2;
+ List<DoubleMetric> dd = m.get(tt);
+ if (dd == null) {
+ logger.warn("metric outside range " + new Date(tt) + " " + new Date(start) + " " + new Date(end));
+ continue;
+ }
+ dd.add(d);
+ }
+ EList<DoubleMetric> res = new BasicEList<DoubleMetric>();
+ int i = 1;
+ for (long t : SortUtil.sort(m.keySet())) {
+ if (i++ == m.keySet().size() && m.get(t).size() == 0)
+ continue; // ignore last timebin if empty.
+ res.add(aggregateList(path, attr, t, m.get(t), option.getAggregationType()));
+ }
+ return res;
+
+ }
+
+ private static DoubleMetric aggregateList(String path, EAttribute attr, long t, List<DoubleMetric> l,
+ AggregationMetricValueOptionType aggregationType) {
+ DoubleMetric d = MetricsFactory.eINSTANCE.createDoubleMetric();
+ d.setTime(t);
+ d.setResourceName(path);
+ d.setMetricName(attr.getName());
+ if (l.size() == 0) {
+ switch (aggregationType) {
+ case AVERAGE:
+ d.setValue(0.0);
+ break;
+ case COUNT:
+ d.setValue(0.0);
+ break;
+ case SUM:
+ d.setValue(0.0);
+ break;
+ case MAX:
+ d.setValue(0.0);
+ break;
+ case MIN:
+ d.setValue(0.0);
+ break;
+ }
+ } else {
+ double v;
+ switch (aggregationType) {
+ case MAX:
+ v = Double.NEGATIVE_INFINITY;
+ break;
+ case MIN:
+ v = Double.POSITIVE_INFINITY;
+ break;
+ default:
+ v = 0.0;
+ }
+ for (DoubleMetric dd : l) {
+ double vv = dd.getValue();
+ switch (aggregationType) {
+ case SUM:
+ case AVERAGE:
+ v += vv;
+ break;
+ case COUNT:
+ v++;
+ break;
+ case MAX:
+ if (v < vv)
+ v = vv;
+ break;
+ case MIN:
+ if (v > vv)
+ v = vv;
+ break;
+ }
+ }
+ switch (aggregationType) {
+ case AVERAGE:
+ v = v / l.size();
+ break;
+ default:
+ break;
+ }
+ d.setValue(v);
+ }
+ return d;
+ }
+
+ public EList<DoubleMetric> getValuesAll(String path, EList<String> metrics, Long start, Long end, MetricValueOption option,
+ boolean relativeInterval) {
+ EList<DoubleMetric> l = new BasicEList<DoubleMetric>();
+ // System.err.println("getValuesAll: " + path + " " + metrics +
+ // " start=" + start + " end=" + end);
+ for (EObject o : server.findAll(path)) {
+ for (String m : metrics) {
+ EStructuralFeature f = o.eClass().getEStructuralFeature(m);
+ if (!(f instanceof EAttribute))
+ continue;
+ Object a = o.eGet(f);
+ if (!(a instanceof MetricAttribute))
+ continue;
+ l.addAll(getValues((MetricAttribute) a, (EAttribute) f, start, end, ManagementServer.object2ref(o), option,
+ relativeInterval));
+ }
+ }
+ return l;
+ }
+
+ public void initAttribute(EObject o, String aName) {
+ MetricStore store = findStore(o);
+ EAttribute attr = (EAttribute) o.eClass().getEStructuralFeature(aName);
+ String path = ManagementServer.relativeObject2ref(server.getObject(), o) + "/" + aName;
+ String aType = attr.getEAttributeType().getName();
+ store.getMeasurement(path,new Date());
+ store.initAttribute(path, aType);
+// System.err.println("XYZ " + path + " " + aType + " " + o.eGet(attr));
+ }
+
+ public void setLongMetric(EObject o, String attr, long v, boolean force) {
+// System.err.println "XYZ $o $attr ${o[attr]} $v $force"
+ EStructuralFeature f = o.eClass().getEStructuralFeature(attr);
+ if (f instanceof EAttribute) {
+ Object m = o.eGet(f);
+ if (m == null) {
+ initAttribute(o,attr);
+ m = o.eGet(f);
+ }
+ if (m instanceof LongMetricAttribute) {
+ LongMetricAttribute m1 = (LongMetricAttribute) m;
+ m1.setValue(v,force);
+ return;
+ }
+ }
+ logger.warn("Unable to setLongMetric" + o.getClass().getName() + "@" + attr);
+ }
+
+ public void setDateMetric(EObject o, String attr, Date v) {
+ setDateMetric(o, attr, v, new Date());
+ }
+ public void setDateMetric(EObject o, String attr, Date v, Date when) {
+// System.err.println "XYZ $o $attr ${o[attr]} $v $force"
+ EStructuralFeature f = o.eClass().getEStructuralFeature(attr);
+ if (f instanceof EAttribute) {
+ Object m = o.eGet(f);
+ if (m == null) {
+ initAttribute(o,attr);
+ m = o.eGet(f);
+ }
+ if (m instanceof DateMetricAttribute) {
+ DateMetricAttribute m1 = (DateMetricAttribute) m;
+ m1.add(when, v.getTime());
+ return;
+ }
+ }
+ logger.warn("Unable to setDateMetric" + o.getClass().getName() + "@" + attr);
+ }
+
+ public void addIncreasingULongMetric(EObject o, String attr, long v, boolean force) {
+// System.err.println "XYZ $o $attr ${o[attr]} $v $force"
+ EStructuralFeature f = o.eClass().getEStructuralFeature(attr);
+ if (f instanceof EAttribute) {
+ Object m = o.eGet(f);
+ if (m == null) {
+ initAttribute(o,attr);
+ m = o.eGet(f);
+ }
+ if (m instanceof IncreasingULongMetricAttribute) {
+ IncreasingULongMetricAttribute m1 = (IncreasingULongMetricAttribute) m;
+ m1.increase(v,force);
+ return;
+ }
+ }
+ logger.warn("Unable to addIncreasingULongMetric" + o.getClass().getName() + "@" + attr);
+ }
+
+
+}
diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/metrics/MetricStore.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/metrics/MetricStore.java new file mode 100644 index 0000000..3fd1b37 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/metrics/MetricStore.java @@ -0,0 +1,288 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager.metrics; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Date; +import java.util.List; + +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.impl.EAnnotationImpl; +import org.json.JSONObject; + +import org.openecomp.ncomp.core.OperationalState; +import org.openecomp.ncomp.core.alerts.Alert; +import org.openecomp.ncomp.core.alerts.AlertContainer; +import org.openecomp.ncomp.core.alerts.ThresholdAlert; +import org.openecomp.ncomp.core.types.metrics.*; +import org.openecomp.ncomp.sirius.manager.*; +import org.openecomp.ncomp.utils.SortUtil; +import org.openecomp.ncomp.utils.journaling.JournalingDateObject; +import org.openecomp.ncomp.utils.journaling.JournalingHashMap; +import org.openecomp.ncomp.webservice.utils.DateUtils; + +import static org.openecomp.ncomp.sirius.manager.ManagementServerUtils.printStackTrace; + +public class MetricStore implements IMetricStore { + public static final Logger logger = Logger.getLogger(MetricStore.class); + JournalingDateObject<JournalingHashMap<MetricDailyMeasurement>> metrics; + private EObject o; + private MetricManager manager; + public MetricStore(String dir, EObject o, MetricManager m) { + metrics = new JournalingDateObject<JournalingHashMap<MetricDailyMeasurement>>(dir, JournalingHashMap.class); + this.o = o; + this.manager = m; + } + + public void addDoubleValue(String path, Date d, Double v, String aType) { + MetricDailyMeasurement p = getMeasurement(path,d); + initAttribute(path,aType); + p.add(d,v); + checkAlerts(p,d,path,v); + } + + public void addLongValue(String path, Date d, Long v, String aType, boolean isDelta) { + MetricDailyMeasurement p = getMeasurement(path,d); + MetricAttribute a = initAttribute(path,aType); + if (isDelta && p.getLast() != null) { + v += ((LongMetricMeasurement) p.getLast()).v; + } + p.add(d,v); + if (a instanceof DateMetricAttribute) { + v = new Date().getTime() - v; + } + checkAlerts(p,d,path,v); + } + public void addStringValue(String path, Date d, String v, String aType) { + MetricDailyMeasurement p = getMeasurement(path,d); + initAttribute(path,aType); + p.add(d,v); +// checkAlerts(p,d,path,v); + } + + + public void addStringValue(String path, Date d, String v) { + MetricDailyMeasurement p = getMeasurement(path,d); + // need to convert the String to the right kind of value. + MetricAttribute aa = initAttribute(path,null); + if (aa instanceof IncreasingULongMetricAttribute || aa instanceof LongMetricAttribute) { + // convert v to long + long v1 = Long.parseLong(v); + p.add(d,v1); + checkAlerts(p,d,path,v1); + return; + } + if (aa instanceof DoubleMetricAttribute) { + // convert v to double + double v1 = Double.parseDouble(v); + p.add(d,v1); + checkAlerts(p,d,path,v1); + return; + } + if (aa == null) { + logger.warn("unable to find measurement attribute for path: " + path); + return; + } + throw new RuntimeException("Should not get here"); + } + + private void checkAlerts(MetricDailyMeasurement p, Date d, String path, double v) { + if (!d.equals(p.getLast().d)) return; + if (o == null) throw new RuntimeException("Cannot check Alerts without EObject"); + Subject s = manager.server.findAndCreateSubject(o,path); + if (s == null || s.o == null || s.attr == null) return; + if (s.o instanceof AlertContainer) { + MetricAttribute aa = (MetricAttribute) s.o.eGet(s.attr); + AlertContainer alerts = (AlertContainer) s.o; + for (Alert a : alerts.getAlerts()) { + if (ManagementServer.getOperationalState(a) == OperationalState.SUSPENDED) continue; + try { + if (a instanceof ThresholdAlert) { + ThresholdAlert a1 = (ThresholdAlert) a; + if (a1.getDuration() != null) { + v = MetricUtils.getAverage(aa,a1.getDuration()); + } + if (!s.attr.getName().equals(a1.getMetricName())) continue; + if (a1.getLowerBound() != null && v < a1.getLowerBound()) { + String path2 = ManagementServer.object2ref(s.o) + path + "/" + a1.getMetricName(); + logger.warn("Metric Alert: path={" + path2 +"} sev={" + a1.getSeverity() +"} " + a1.getMetricName() + " is too low " + v + " < " + a1.getUpperBound()); + } + if (a1.getUpperBound() != null && v > a1.getUpperBound()) { + String path2 = ManagementServer.object2ref(s.o); + logger.warn("Metric Alert: path={" + path2 +"} sev={" + a1.getSeverity() +"} " + a1.getMetricName() + " is too high " + v + " > " + a1.getUpperBound()); + } + return; + } + logger.warn("unknown alert class: " + a.eClass().getName()); + } catch (Exception e) { + a.setOperationalState(OperationalState.SUSPENDED); + logger.error("error in alert (now disabled): " + e); + } + } + } + + } + protected MetricAttribute initAttribute(String path, String aType) { + if (o == null) throw new RuntimeException("Cannot init attribute without EObject"); + Subject s; + try { + s = manager.server.findAndCreateSubject(o,path); + } catch (Exception e) { + logger.warn("Unable to create object path={" + path + "} " + e); + System.err.println("Unable to create object for: " + path + " " + e); + printStackTrace(e); + return null; + } + if (s == null || s.o == null || s.attr == null) return null; + if (s.o.eGet(s.attr) != null) return (MetricAttribute) s.o.eGet(s.attr); + String eName = (aType == null) ? s.attr.getEType().getName() : aType; + MetricAttribute aa = null; + if (eName.equals("IncreasingULongMetricAttribute")) { + aa = new IncreasingULongMetricAttribute(); + } + else if (eName.equals("LongMetricAttribute")) { + aa = new LongMetricAttribute(); + } + else if (eName.equals("DoubleMetricAttribute")) { + aa = new DoubleMetricAttribute(); + } + else if (eName.equals("DateMetricAttribute")) { + aa = new DateMetricAttribute(); + } + else if (eName.equals("StringMetricAttribute")) { + aa = new StringMetricAttribute(); + } + else throw new RuntimeException("Unknown type: " + eName + " for path: " + path); +// System.err.println("TYPES:" + ManagementServer.object2ref(s.o)+ " " + s.attr.getEType().getName() + " " + aa); + s.o.eSet(s.attr,aa); + aa.setup(this, path); + return aa; + } + + MetricDailyMeasurement getMeasurement(String path, Date d) { + JournalingHashMap<MetricDailyMeasurement> m = metrics.get(d); + MetricDailyMeasurement p = m.get(path); + if (p == null) { + p = m.newKey(path, MetricDailyMeasurement.class); + } + return p; + } + + public MetricMeasurement getLast(String path) { + Date now = new Date(); + MetricDailyMeasurement p = metrics.get(now).get(path); + if (p != null) { + MetricMeasurement m = p.getLast(); + if (m != null) return m; + } + now.setTime(now.getTime()-24*3600000); + p = metrics.get(now).get(path); + if (p != null) { + MetricMeasurement m = p.getLast(); + if (m != null) return m; + } + return null; + } + public MetricMeasurement getLast2(String path) { + Date now = new Date(); + MetricDailyMeasurement p = metrics.get(now).get(path); + if (p != null) { + MetricMeasurement m = p.getLast(); + if (m != null) return p.getLast2(); + } + now.setTime(now.getTime()-24*3600000); + p = metrics.get(now).get(path); + if (p != null) { + MetricMeasurement m = p.getLast(); + if (m != null) return p.getLast2(); + } + return null; + } + + private Comparator<? super MetricMeasurement> comp = new Comparator<MetricMeasurement>() { + @Override + public int compare(MetricMeasurement t1, MetricMeasurement t2) { + return ((Long)t1.d.getTime()).compareTo(t2.d.getTime()); + } + }; + + public List<MetricMeasurement> getValues(String path, Date start, Date end) { + List<MetricMeasurement> res = new ArrayList<MetricMeasurement>(); + for (Date d: DateUtils.dateRange(start, end, DateUtils.stringToDuration("1day"))) { + MetricDailyMeasurement p = metrics.get(d).get(path); + if (p == null) continue; + for (MetricMeasurement m : p.l) { + if (m.d.before(start) || m.d.after(end)) continue; + res.add(m); + } + } + return SortUtil.sort(res, comp); + } + + public void save() { + metrics.save(); + } + long lastUpdate = 0; + public boolean save(long i) { + long now = new Date().getTime(); + if (lastUpdate + i < now) { + save(); + lastUpdate = new Date().getTime(); + return true; + } + return false; + } + public void close() { + metrics.close(); + } + + public JSONObject toJson() { + JSONObject json = new JSONObject(); + json.put("metrics", metrics.toJson()); + return json ; + } + + public void initStore() { + Date yesterday = DateUtils.dateFromString("-1day"); + Date today = new Date(); + for (Date d: DateUtils.dateRange(yesterday , today, DateUtils.stringToDuration("1day"))) { + List<String> l = new ArrayList<String>(metrics.get(d).keySet()); + for (String path: l) { + // TODO the type need to be persistent. + try { + if (o != null) initAttribute(path,null); + } catch (Exception e) { + logger.warn("unable to init: " + path); + printStackTrace(e); + } + } + } + } + + public EObject getObject() { + return o; + } + +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/metrics/MetricTest.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/metrics/MetricTest.java new file mode 100644 index 0000000..656de89 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/metrics/MetricTest.java @@ -0,0 +1,116 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager.metrics; + +import java.io.File; +import java.util.List; + +import junit.framework.TestCase; + +import org.openecomp.ncomp.core.types.metrics.DoubleMetricAttribute; +import org.openecomp.ncomp.core.types.metrics.DoubleMetricMeasurement; +import org.openecomp.ncomp.core.types.metrics.IncreasingULongMetricAttribute; +import org.openecomp.ncomp.core.types.metrics.LongMetricAttribute; +import org.openecomp.ncomp.core.types.metrics.LongMetricMeasurement; +import org.openecomp.ncomp.webservice.utils.DateUtils; +import org.openecomp.ncomp.webservice.utils.FileUtils; + +public class MetricTest extends TestCase { + + public void test_case1() { + String dir = "data/metrics/test1"; + File f = new File(dir); + if (f.exists()) FileUtils.deleteDirectory(f); + MetricStore store = new MetricStore(dir,null,null); + DoubleMetricAttribute d = new DoubleMetricAttribute(); + d.setup(store, "foobar"); + d.add(DateUtils.dateFromString("-10min"), 1.0); + d.add(DateUtils.dateFromString("-8min"), 13.0); + d.add(DateUtils.dateFromString("-6min"), 12.0); + d.add(DateUtils.dateFromString("-13min"), 11.0); + assertEquals(12.0,d.getValue()); + List<DoubleMetricMeasurement> l = d.getValues(DateUtils.dateFromString("-1hour"),DateUtils.dateFromString("-0min")); + assertEquals(11.0,l.get(0).v); + assertEquals(1.0,l.get(1).v); + assertEquals(12.0,l.get(3).v); + } + + public void test_case_Long() { + String dir = "data/metrics/test2"; + File f = new File(dir); + if (f.exists()) FileUtils.deleteDirectory(f); + MetricStore store = new MetricStore(dir,null,null); + LongMetricAttribute d = new LongMetricAttribute(); + d.setup(store, "foobar"); + d.add(DateUtils.dateFromString("-10min"), 1L); + d.add(DateUtils.dateFromString("-8min"), 13L); + d.add(DateUtils.dateFromString("-6min"), 12L); + d.add(DateUtils.dateFromString("-13min"), 11L); + assertEquals((Long) 12L,d.getValue()); + List<LongMetricMeasurement> l = d.getValues(DateUtils.dateFromString("-1hour"),DateUtils.dateFromString("-0min")); + assertEquals(11L,l.get(0).v); + assertEquals(1L,l.get(1).v); + assertEquals(12L,l.get(3).v); + } + public void test_case_IncreasingULong() { + String dir = "data/metrics/test3"; + File f = new File(dir); + if (f.exists()) FileUtils.deleteDirectory(f); + MetricStore store = new MetricStore(dir,null,null); + IncreasingULongMetricAttribute d = new IncreasingULongMetricAttribute(); + d.setup(store, "foobar"); + d.add(DateUtils.dateFromString("-10min"), 1L); + d.add(DateUtils.dateFromString("-8min"), 13L); + d.add(DateUtils.dateFromString("-6min"), 12L); + d.add(DateUtils.dateFromString("-13min"), 11L); + List<LongMetricMeasurement> l = d.getDeltaValues(DateUtils.dateFromString("-1hour"),DateUtils.dateFromString("-0min")); + assertEquals(-10L,l.get(0).v); + assertEquals(12L,l.get(1).v); + assertEquals(-1L,l.get(2).v); + assertEquals((-1L),d.getValue()); + } + + public void test_case_IncreasingULong2() { + String dir = "data/metrics/test4"; + File f = new File(dir); + if (f.exists()) FileUtils.deleteDirectory(f); + MetricStore store = new MetricStore(dir,null,null); + IncreasingULongMetricAttribute d = new IncreasingULongMetricAttribute(); + d.setup(store, "foobar"); + d.add(DateUtils.dateFromString("-13min"), Long.MAX_VALUE - 11L); + d.add(DateUtils.dateFromString("-10min"), Long.MAX_VALUE); + d.add(DateUtils.dateFromString("-8min"), Long.MIN_VALUE); + d.add(DateUtils.dateFromString("-6min"), Long.MIN_VALUE + 12L); + List<LongMetricMeasurement> l = d.getDeltaValues(DateUtils.dateFromString("-1hour"),DateUtils.dateFromString("-0min")); + assertEquals(11L,l.get(0).v); + assertEquals(1L,l.get(1).v); + assertEquals(12L,l.get(2).v); + assertEquals(3, l.size()); + assertEquals((12L),d.getValue()); + store.close(); + MetricStore store2 = new MetricStore(dir,null,null); + IncreasingULongMetricAttribute d2 = new IncreasingULongMetricAttribute(); + d2.setup(store2, "foobar"); + assertEquals((12L),d2.getValue()); + } + +} diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/metrics/MetricUtils.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/metrics/MetricUtils.java new file mode 100644 index 0000000..08d3bf5 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/metrics/MetricUtils.java @@ -0,0 +1,45 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager.metrics;
+
+import java.util.Date;
+import java.util.List;
+
+import org.openecomp.ncomp.core.types.metrics.DoubleMetricMeasurement;
+import org.openecomp.ncomp.core.types.metrics.MetricAttribute;
+import org.openecomp.ncomp.webservice.utils.DateUtils;
+
+public class MetricUtils {
+
+ public static double getAverage(MetricAttribute aa, String duration) {
+ Date now = new Date();
+ Date past = new Date(now.getTime()-DateUtils.stringToDuration(duration));
+ List<DoubleMetricMeasurement> l = aa.getValuesDouble(past, now);
+ if (l.size() == 0) return 0.0;
+ double sum = 0.0;
+ for (DoubleMetricMeasurement m : l) {
+ sum += m.v;
+ }
+ return sum/l.size();
+ }
+
+}
diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/properties/MD5Checksum.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/properties/MD5Checksum.java new file mode 100644 index 0000000..43ee90b --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/properties/MD5Checksum.java @@ -0,0 +1,101 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager.properties;
+
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.security.MessageDigest;
+import java.util.Date;
+
+import org.openecomp.ncomp.sirius.manager.ManagementServerUtils;
+
+public class MD5Checksum {
+
+ public static String createFileChecksum(String filename) {
+ try {
+ InputStream fis = null;
+ MessageDigest complete = null;
+ try {
+ fis = new FileInputStream(filename);
+ byte[] buffer = new byte[1024];
+ complete = MessageDigest.getInstance("MD5");
+ int numRead = 0;
+ while (numRead != -1) {
+ numRead = fis.read(buffer);
+ if (numRead > 0) {
+ complete.update(buffer, 0, numRead);
+ }
+ }
+ } catch (Exception e) {
+ ManagementServerUtils.printStackTrace(e);
+ } finally {
+ if (fis != null)
+ fis.close();
+ }
+ return bytes2hex(complete.digest());
+ } catch (Exception e) {
+ return random();
+ }
+ }
+
+ public static String createChecksum(String s) {
+ try {
+ MessageDigest complete = MessageDigest.getInstance("MD5");
+ complete.update(s.getBytes());
+ return bytes2hex(complete.digest());
+ } catch (Exception e) {
+ ManagementServerUtils.printStackTrace(e);
+ return random();
+ }
+ }
+
+ public static String createChecksum(byte[] bytes) {
+ try {
+ MessageDigest complete = MessageDigest.getInstance("MD5");
+ complete.update(bytes);
+ return bytes2hex(complete.digest());
+ } catch (Exception e) {
+ ManagementServerUtils.printStackTrace(e);
+ return random();
+ }
+ }
+
+ // a byte array to a HEX string
+ private static String bytes2hex(byte[] b) throws Exception {
+ String result = "";
+ for (int i = 0; i < b.length; i++) {
+ result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
+ }
+ return result;
+ }
+
+ private synchronized static String random() {
+ long t = new Date().getTime();
+ try {
+ Thread.sleep(1);
+ } catch (InterruptedException e) {
+ ManagementServerUtils.printStackTrace(e);
+ }
+ return Long.toString(t);
+ }
+
+}
diff --git a/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/properties/PropertyManager.java b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/properties/PropertyManager.java new file mode 100644 index 0000000..f8d7361 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/org/openecomp/ncomp/sirius/manager/properties/PropertyManager.java @@ -0,0 +1,114 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.sirius.manager.properties;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.Date;
+import java.util.HashMap;
+
+import org.apache.log4j.Logger;
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+
+import org.openecomp.ncomp.sirius.manager.ManagementServer;
+import org.openecomp.ncomp.sirius.manager.ManagementServerUtils;
+import org.openecomp.ncomp.webservice.utils.FileUtils;
+
+public class PropertyManager {
+ public static final Logger logger = Logger.getLogger(PropertyManager.class);
+
+ private Object propDir;
+ private ManagementServer server;
+ private HashMap<String, String> checksums = new HashMap<String, String>();
+
+ public PropertyManager(ManagementServer managementServer) {
+ server = managementServer;
+ propDir = server.getProps().getProperty("properties.dir", "data/properties");
+ }
+
+ public void updatePropertries(EObject o, EList<AbstractProperty> props) {
+ for (AbstractProperty ap : props) {
+ if (ap instanceof ModuleProperty) {
+ ModuleProperty mp = (ModuleProperty) ap;
+ updateModules(o, mp);
+ continue;
+ }
+ if (ap instanceof Property) {
+ Property p = (Property) ap;
+ Date now = new Date();
+ if (!p.getName().startsWith("/"))
+ p.setName("/" + p.getName());
+ String file = propDir + ManagementServer.object2ref(o) + p.getName();
+ if (!checksums.containsKey(file)) {
+ checksums.put(file, MD5Checksum.createFileChecksum(file));
+ }
+ String checksum = MD5Checksum.createChecksum(p.getValue());
+ if (checksum.equals(checksums.get(file)))
+ continue;
+ String file1 = file + "." + now.getTime();
+ writeFile(file1, p.getValue());
+ File f1 = writeFile(file1 + ".1", p.getValue());
+ File f2 = new File(file);
+ f1.renameTo(f2);
+ logger.info("Wrote " + file);
+ }
+ }
+ }
+
+ private File writeFile(String file1, String value) {
+ File f = new File(file1);
+ f.getParentFile().mkdirs();
+ OutputStreamWriter w = FileUtils.filename2writer(file1);
+ try {
+ w.append(value);
+ w.close();
+ } catch (IOException e) {
+ logger.warn("Unable tor write file: " + file1 + " " + e);
+ ManagementServerUtils.printStackTrace(e);
+ }
+ return f;
+ }
+
+ private void updateModules(EObject o, ModuleProperty mp) {
+ if (o instanceof ModuleContainer) {
+ ModuleContainer c = (ModuleContainer) o;
+ EList<Module> l = new BasicEList<Module>();
+ boolean found = false;
+ for (Module m : c.getModules()) {
+ if (m.getName().equals(mp.getName())) {
+ found = true;
+ l.add(EcoreUtil.copy(mp));
+ }
+ else
+ l.add(EcoreUtil.copy(m));
+ }
+ if (!found) l.add(EcoreUtil.copy(mp));
+ c.getModules().clear();
+ c.getModules().addAll(l);
+ }
+ }
+
+}
diff --git a/ncomp-sirius-manager-server/src/main/java/swagger-api.json b/ncomp-sirius-manager-server/src/main/java/swagger-api.json new file mode 100644 index 0000000..fc58e92 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/java/swagger-api.json @@ -0,0 +1,19 @@ +{ + "swagger": "2.0", + "host": "localhost:9998", + "basePath": "", + "schemes": ["http"], + "info": { + "description": "TBD", + "version": "0.1.0", + "title": "Sirius Server", + "termsOfService": "TBD", + "contact": {"email": "TBD"}, + "license": { + "name": "TBD", + "url": "http://TDB" + } + }, + "paths": { + } +} diff --git a/ncomp-sirius-manager-server/src/main/resources/swagger-api.json b/ncomp-sirius-manager-server/src/main/resources/swagger-api.json new file mode 100644 index 0000000..c3e4d99 --- /dev/null +++ b/ncomp-sirius-manager-server/src/main/resources/swagger-api.json @@ -0,0 +1,17 @@ +{ + "swagger": "2.0", + "host": "????", + "basePath": "", + "schemes": ["http"], + "info": { + "description": "TBD", + "version": "0.1.0", + "title": "Sirius Server", + "termsOfService": "TBD", + "contact": {"email": "TBD"}, + "license": { + "name": "TBD", + "url": "http://TDB" + } + } +}
\ No newline at end of file |