| /******************************************************************************* |
| * Copyright (c) 2019 Boeing. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Boeing - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.ote.simple.test.environment.outfile; |
| |
| import java.io.BufferedOutputStream; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.net.InetAddress; |
| import java.net.UnknownHostException; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.logging.Handler; |
| import java.util.logging.LogRecord; |
| import java.util.zip.ZipEntry; |
| import java.util.zip.ZipOutputStream; |
| |
| import org.eclipse.osee.framework.jdk.core.persistence.XmlizableStream; |
| import org.eclipse.osee.ote.core.environment.interfaces.ITestPoint; |
| import org.eclipse.osee.ote.core.log.record.ScriptResultRecord; |
| import org.eclipse.osee.ote.core.log.record.TestPointRecord; |
| import org.eclipse.osee.ote.core.log.record.json.LogRecordModule; |
| import org.eclipse.osee.ote.core.testPoint.CheckGroup; |
| import org.eclipse.osee.ote.core.testPoint.CheckPoint; |
| import org.eclipse.osee.ote.core.testPoint.Operation; |
| import org.eclipse.ote.simple.test.environment.outfile.xml.TestPointResults; |
| import org.eclipse.ote.simple.test.environment.outfile.xml.TimeSummary; |
| |
| import com.fasterxml.jackson.annotation.JsonInclude; |
| import com.fasterxml.jackson.annotation.JsonTypeInfo; |
| import com.fasterxml.jackson.core.JsonGenerationException; |
| import com.fasterxml.jackson.databind.JsonMappingException; |
| import com.fasterxml.jackson.databind.MapperFeature; |
| import com.fasterxml.jackson.databind.ObjectMapper; |
| import com.fasterxml.jackson.databind.SerializationFeature; |
| import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder; |
| |
| /** |
| * @author Andy Jury |
| */ |
| public class ScriptJsonOutLogHandler extends Handler { |
| private Map<String, Object> minimum = new HashMap<String, Object>(); |
| private final ObjectMapper mapper = new ObjectMapper(); |
| private File outfile; |
| private ZipOutputStream zip; |
| private String distrStatement; |
| |
| public ScriptJsonOutLogHandler(final File outFile, final String distributionStatement) { |
| super(); |
| outfile = outFile; |
| distrStatement = distributionStatement; |
| } |
| |
| public ScriptJsonOutLogHandler(File outFile) { |
| this(outFile, "DISTRO_STATEMENT_HERE"); |
| } |
| |
| @Override |
| public synchronized void publish(final LogRecord logRecord) { |
| if (isLoggable(logRecord)) { |
| try { |
| publisihMinimum(logRecord); |
| } catch (Exception ex) { |
| logError(ex); |
| } |
| } |
| } |
| |
| private void publisihMinimum(LogRecord logRecord) { |
| try { |
| minimum.put("machineName", InetAddress.getLocalHost().getHostName()); |
| } catch (UnknownHostException ex) { |
| logError(ex, "Unable to determine machine name"); |
| } |
| if (logRecord instanceof ScriptResultRecord) { |
| ScriptResultRecord srr = (ScriptResultRecord) logRecord; |
| minimum.put("ScriptName", logRecord.getMessage()); |
| for (XmlizableStream rec : srr.getResults()) { |
| if (rec instanceof TimeSummary) { |
| TimeSummary ts = (TimeSummary) rec; |
| minimum.put("elapsedTime", ts.getElapsedTime()); |
| minimum.put("startTime", ts.getStartTime()); |
| minimum.put("endTime", ts.getEndTime()); |
| } else if (rec instanceof TestPointResults) { |
| Map<String, Object> results = new HashMap<String, Object>(); |
| results.put("passes", ((TestPointResults) rec).getPasses()); |
| results.put("fails", ((TestPointResults) rec).getFails()); |
| results.put("aborted", ((TestPointResults) rec).isAborted()); |
| results.put("total", ((TestPointResults) rec).getTotal()); |
| minimum.put("results", results); |
| } |
| } |
| } else if (logRecord instanceof TestPointRecord) { |
| @SuppressWarnings("unchecked") |
| List<Object> testPoints = (List<Object>) minimum.get("testPoints"); |
| if (testPoints == null) { |
| testPoints = new ArrayList<Object>(); |
| minimum.put("testPoints", testPoints); |
| } |
| ITestPoint testPoint = ((TestPointRecord) logRecord).getTestPoint(); |
| int number = ((TestPointRecord) logRecord).getNumber(); |
| boolean overall = testPoint.isPass(); |
| handleTestPoint(testPoint, testPoints, number, "", overall, String.valueOf(number)); |
| } |
| } |
| |
| private void handleTestPoint(ITestPoint testPoint, List<Object> testPoints, int number, String groupName, boolean overallPass, String levelNum) { |
| if (testPoint instanceof CheckPoint) { |
| Map<String, Object> point = convertCheckPoint((CheckPoint) testPoint, number, groupName, overallPass, levelNum); |
| testPoints.add(point); |
| } else if (testPoint instanceof CheckGroup) { |
| CheckGroup group = (CheckGroup) testPoint; |
| ArrayList<ITestPoint> groupPoints = group.getTestPoints(); |
| Operation op = group.getOperation(); |
| String curGroupName = group.getGroupName() + " [" + op.getName() + "]"; |
| for (int i = 0; i < groupPoints.size(); i++) { |
| ITestPoint tp = groupPoints.get(i); |
| handleTestPoint(tp, testPoints, number, curGroupName, overallPass, levelNum + "." + (i + 1)); |
| } |
| } |
| } |
| |
| private Map<String, Object> convertCheckPoint(CheckPoint checkPoint, int number, String groupName, boolean overallPass, String levelNum) { |
| Map<String, Object> tpMap = new HashMap<String, Object>(); |
| tpMap.put("name", checkPoint.getTestPointName()); |
| tpMap.put("expected", checkPoint.getExpected()); |
| tpMap.put("actual", checkPoint.getActual()); |
| tpMap.put("pass", checkPoint.isPass()); |
| tpMap.put("number", number); |
| tpMap.put("overall", overallPass); |
| if (!groupName.isEmpty()) { |
| tpMap.put("groupName", groupName); |
| } |
| tpMap.put("tpLevel", levelNum); |
| return tpMap; |
| } |
| |
| private boolean prepareToFlush() { |
| setupJson(); |
| return setupOutputFile(); |
| } |
| |
| private void setupJson() { |
| mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); |
| mapper.configure(MapperFeature.AUTO_DETECT_FIELDS, false); |
| mapper.configure(MapperFeature.AUTO_DETECT_GETTERS, false); |
| mapper.configure(MapperFeature.AUTO_DETECT_IS_GETTERS, false); |
| mapper.configure(SerializationFeature.INDENT_OUTPUT, true); |
| mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); |
| mapper.registerModule(new LogRecordModule()); |
| TypeResolverBuilder<?> typeResolver = new TmoTypeResolverBuilder(); |
| typeResolver.init(JsonTypeInfo.Id.CLASS, null); |
| typeResolver.inclusion(JsonTypeInfo.As.PROPERTY); |
| typeResolver.typeProperty("@CLASS"); |
| mapper.setDefaultTyping(typeResolver); |
| } |
| |
| private boolean setupOutputFile() { |
| boolean result = true; |
| String path; |
| try { |
| path = outfile.getCanonicalPath(); |
| path = path.substring(0, path.length() - 1) + 'z'; |
| File file = new File(path); |
| FileOutputStream fos; |
| try { |
| fos = new FileOutputStream(file); |
| BufferedOutputStream bos = new BufferedOutputStream(fos); |
| zip = new ZipOutputStream(bos); |
| } catch (FileNotFoundException ex) { |
| logError(ex, "Zip file creation failed"); |
| result = false; |
| } |
| } catch (IOException ex) { |
| logError(ex, "Failed to get canaonical path from outFile"); |
| result = false; |
| } |
| return result; |
| } |
| |
| public synchronized void flushRecords() { |
| if (prepareToFlush()) { |
| writeZipEntry("Minimum", minimum); |
| writeZipEntry("DistributionStatement", distrStatement); |
| } |
| } |
| |
| private void writeZipEntry(final String basename, final Object object) { |
| try { |
| byte[] buffer = new byte[1024]; |
| File temp = File.createTempFile(basename, "json"); |
| mapper.writeValue(temp, object); |
| FileInputStream input = new FileInputStream(temp); |
| ZipEntry entry = new ZipEntry(basename + ".json"); |
| zip.putNextEntry(entry); |
| int len; |
| while ((len = input.read(buffer)) > 0) { |
| zip.write(buffer, 0, len); |
| } |
| input.close(); |
| temp.delete(); |
| } catch (JsonGenerationException ex) { |
| logError(ex); |
| } catch (JsonMappingException ex) { |
| logError(ex); |
| } catch (IOException ex) { |
| logError(ex); |
| } |
| } |
| |
| @Override |
| public void close() throws SecurityException { |
| try { |
| zip.close(); |
| } catch (Exception ex) { |
| logError(ex); |
| } |
| } |
| |
| @Override |
| public void flush() { |
| // don't call this method |
| } |
| |
| private void logError(final Exception ex) { |
| logError(ex); |
| } |
| |
| private void logError(final Exception ex, final String message) { |
| if (message != null && message.trim().length() > 0) { |
| System.err.println(message); |
| } |
| if (ex != null) { |
| ex.printStackTrace(); |
| } else { |
| Throwable throwable = new Throwable(); |
| throwable.printStackTrace(); |
| } |
| } |
| } |