1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you
5  * may not use this file except in compliance with the License. You may
6  * obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13  * implied. See the License for the specific language governing
14  * permissions and limitations under the License.
15  */
16 
17 package com.android.vts.entity;
18 
19 import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode;
20 import com.android.vts.proto.VtsReportMessage.VtsProfilingType;
21 import com.google.appengine.api.datastore.Entity;
22 import com.google.appengine.api.datastore.Key;
23 import com.google.appengine.api.datastore.KeyFactory;
24 import com.googlecode.objectify.annotation.Cache;
25 import com.googlecode.objectify.annotation.Id;
26 import com.googlecode.objectify.annotation.Ignore;
27 import com.googlecode.objectify.annotation.Index;
28 import java.util.Date;
29 import java.util.logging.Level;
30 import java.util.logging.Logger;
31 import lombok.Data;
32 import lombok.NoArgsConstructor;
33 
34 import static com.googlecode.objectify.ObjectifyService.ofy;
35 
36 @com.googlecode.objectify.annotation.Entity(name = "ProfilingPoint")
37 @Cache
38 @Data
39 @NoArgsConstructor
40 /** Entity describing a profiling point. */
41 public class ProfilingPointEntity implements DashboardEntity {
42     protected static final Logger logger = Logger.getLogger(ProfilingPointEntity.class.getName());
43     protected static final String DELIMITER = "#";
44 
45     public static final String KIND = "ProfilingPoint";
46 
47     // Property keys
48     public static final String TEST_NAME = "testName";
49     public static final String PROFILING_POINT_NAME = "profilingPointName";
50     public static final String TYPE = "type";
51     public static final String REGRESSION_MODE = "regressionMode";
52     public static final String X_LABEL = "xLabel";
53     public static final String Y_LABEL = "yLabel";
54 
55     @Ignore
56     private Key key;
57 
58     /** ProfilingPointEntity testName field */
59     @Id
60     private String name;
61 
62     /** ProfilingPointEntity profilingPointName field */
63     @Index
64     private String profilingPointName;
65 
66     /** ProfilingPointEntity testName field */
67     @Index
68     private String testName;
69 
70     /** ProfilingPointEntity type field */
71     private int type;
72 
73     /** ProfilingPointEntity regressionMode field */
74     private int regressionMode;
75 
76     /** ProfilingPointEntity xLabel field */
77     private String xLabel;
78 
79     /** ProfilingPointEntity xLabel field */
80     private String yLabel;
81 
82     /**
83      * When this record was created or updated
84      */
85     @Index
86     Date updated;
87 
88     /**
89      * Create a ProfilingPointEntity object.
90      *
91      * @param testName The name of test containing the profiling point.
92      * @param profilingPointName The name of the profiling point.
93      * @param type The (number) type of the profiling point data.
94      * @param regressionMode The (number) mode to use for detecting regression.
95      * @param xLabel The x axis label.
96      * @param yLabel The y axis label.
97      */
ProfilingPointEntity( String testName, String profilingPointName, int type, int regressionMode, String xLabel, String yLabel)98     public ProfilingPointEntity(
99             String testName,
100             String profilingPointName,
101             int type,
102             int regressionMode,
103             String xLabel,
104             String yLabel) {
105         this.key = createKey(testName, profilingPointName);
106         this.testName = testName;
107         this.profilingPointName = profilingPointName;
108         this.type = type;
109         this.regressionMode = regressionMode;
110         this.xLabel = xLabel;
111         this.yLabel = yLabel;
112         this.updated = new Date();
113     }
114 
115     /**
116      * Get VtsProfilingType from int value.
117      *
118      * @return VtsProfilingType class.
119      */
getVtsProfilingType(int type)120     public VtsProfilingType getVtsProfilingType(int type) {
121         return VtsProfilingType.forNumber(type);
122     }
123 
124     /**
125      * Get VtsProfilingRegressionMode from int value.
126      *
127      * @return VtsProfilingType class.
128      */
getVtsProfilingRegressionMode(int regressionMode)129     public VtsProfilingRegressionMode getVtsProfilingRegressionMode(int regressionMode) {
130         return VtsProfilingRegressionMode.forNumber(regressionMode);
131     }
132 
133     /**
134      * Create a key for a ProfilingPointEntity.
135      *
136      * @param testName The name of test containing the profiling point.
137      * @param profilingPointName The name of the profiling point.
138      * @return a Key object for the ProfilingEntity in the database.
139      */
createKey(String testName, String profilingPointName)140     public static Key createKey(String testName, String profilingPointName) {
141         return KeyFactory.createKey(KIND, testName + DELIMITER + profilingPointName);
142     }
143 
144     /** Saving function for the instance of this class */
145     @Override
save()146     public com.googlecode.objectify.Key<ProfilingPointEntity> save() {
147         return ofy().save().entity(this).now();
148     }
149 
toEntity()150     public Entity toEntity() {
151         Entity profilingPoint = new Entity(key);
152         profilingPoint.setIndexedProperty(TEST_NAME, this.testName);
153         profilingPoint.setIndexedProperty(PROFILING_POINT_NAME, this.profilingPointName);
154         profilingPoint.setUnindexedProperty(TYPE, this.type);
155         profilingPoint.setUnindexedProperty(REGRESSION_MODE, this.regressionMode);
156         profilingPoint.setUnindexedProperty(X_LABEL, this.xLabel);
157         profilingPoint.setUnindexedProperty(Y_LABEL, this.yLabel);
158 
159         return profilingPoint;
160     }
161 
162     /**
163      * Convert an Entity object to a ProfilingPointEntity.
164      *
165      * @param e The entity to process.
166      * @return ProfilingPointEntity object with the properties from e, or null if incompatible.
167      */
168     @SuppressWarnings("unchecked")
fromEntity(Entity e)169     public static ProfilingPointEntity fromEntity(Entity e) {
170         if (!e.getKind().equals(KIND)
171                 || e.getKey().getName() == null
172                 || !e.hasProperty(TEST_NAME)
173                 || !e.hasProperty(PROFILING_POINT_NAME)
174                 || !e.hasProperty(TYPE)
175                 || !e.hasProperty(REGRESSION_MODE)
176                 || !e.hasProperty(X_LABEL)
177                 || !e.hasProperty(Y_LABEL)) {
178             logger.log(
179                     Level.WARNING, "Missing profiling point attributes in entity: " + e.toString());
180             return null;
181         }
182         try {
183             String testName = (String) e.getProperty(TEST_NAME);
184             String profilingPointName = (String) e.getProperty(PROFILING_POINT_NAME);
185             int type = (int) (long) e.getProperty(TYPE);
186             int regressionMode = (int) (long) e.getProperty(REGRESSION_MODE);
187             String xLabel = (String) e.getProperty(X_LABEL);
188             String yLabel = (String) e.getProperty(Y_LABEL);
189 
190             return new ProfilingPointEntity(
191                     testName, profilingPointName, type, regressionMode, xLabel, yLabel);
192         } catch (ClassCastException exception) {
193             // Invalid cast
194             logger.log(Level.WARNING, "Error parsing profiling point entity.", exception);
195         }
196         return null;
197     }
198 }
199