/*******************************************************************************
* Copyright 2013-2015 alladin-IT GmbH
*
* 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.
******************************************************************************/
package at.alladin.rmbt.controlServer;
import java.text.DateFormat;
import java.text.Format;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.UUID;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
import at.alladin.rmbt.db.Client;
import at.alladin.rmbt.db.Test;
import at.alladin.rmbt.db.fields.Field;
import at.alladin.rmbt.db.fields.TimestampField;
import at.alladin.rmbt.db.fields.UUIDField;
import at.alladin.rmbt.shared.Classification;
import at.alladin.rmbt.shared.Helperfunctions;
import at.alladin.rmbt.shared.ResourceManager;
import at.alladin.rmbt.shared.SignificantFormat;
public class TestResultResource extends ServerResource
{
@Post("json")
public String request(final String entity)
{
long startTime = System.currentTimeMillis();
addAllowOrigin();
JSONObject request = null;
final ErrorList errorList = new ErrorList();
final JSONObject answer = new JSONObject();
String answerString;
final String clientIpRaw = getIP();
System.out.println(MessageFormat.format(labels.getString("NEW_TESTRESULT"), clientIpRaw));
if (entity != null && !entity.isEmpty())
// try parse the string to a JSON object
try
{
System.out.println(entity);
request = new JSONObject(entity);
readCapabilities(request);
String lang = request.optString("language");
// Load Language Files for Client
final List<String> langs = Arrays.asList(settings.getString("RMBT_SUPPORTED_LANGUAGES").split(",\\s*"));
if (langs.contains(lang))
{
errorList.setLanguage(lang);
labels = ResourceManager.getSysMsgBundle(new Locale(lang));
}
else
lang = settings.getString("RMBT_DEFAULT_LANGUAGE");
// System.out.println(request.toString(4));
if (conn != null)
{
final Client client = new Client(conn);
final Test test = new Test(conn);
final String testUuid = request.optString("test_uuid");
if (testUuid != null && test.getTestByUuid(UUID.fromString(testUuid)) > 0
&& client.getClientByUid(test.getField("client_id").intValue())
&& "FINISHED".equals(test.getField("status").toString()))
{
final Locale locale = new Locale(lang);
final Format format = new SignificantFormat(2, locale);
final JSONArray resultList = new JSONArray();
final JSONObject jsonItem = new JSONObject();
JSONArray jsonItemList = new JSONArray();
// RMBTClient Info
//also send open-uuid (starts with 'P')
final String openUUID = "P" + ((UUIDField) test.getField("open_uuid")).toString();
jsonItem.put("open_uuid", openUUID);
//and open test-uuid (starts with 'O')
final String openTestUUID = "O" + ((UUIDField) test.getField("open_test_uuid")).toString();
jsonItem.put("open_test_uuid", openTestUUID);
final Date date = ((TimestampField) test.getField("time")).getDate();
final long time = date.getTime();
final String tzString = test.getField("timezone").toString();
final TimeZone tz = TimeZone.getTimeZone(tzString);
jsonItem.put("time", time);
jsonItem.put("timezone", tzString);
final DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
DateFormat.MEDIUM, locale);
dateFormat.setTimeZone(tz);
final String timeString = dateFormat.format(date);
jsonItem.put("time_string", timeString);
final Field fieldDown = test.getField("speed_download");
JSONObject singleItem = new JSONObject();
singleItem.put("title", labels.getString("RESULT_DOWNLOAD"));
final String downloadString = String.format("%s %s",
format.format(fieldDown.doubleValue() / 1000d),
labels.getString("RESULT_DOWNLOAD_UNIT"));
singleItem.put("value", downloadString);
singleItem.put("classification",
Classification.classify(Classification.THRESHOLD_DOWNLOAD, fieldDown.intValue(), capabilities.getClassificationCapability().getCount()));
jsonItemList.put(singleItem);
final Field fieldUp = test.getField("speed_upload");
singleItem = new JSONObject();
singleItem.put("title", labels.getString("RESULT_UPLOAD"));
final String uploadString = String.format("%s %s",
format.format(fieldUp.doubleValue() / 1000d), labels.getString("RESULT_UPLOAD_UNIT"));
singleItem.put("value", uploadString);
singleItem.put("classification",
Classification.classify(Classification.THRESHOLD_UPLOAD, fieldUp.intValue(), capabilities.getClassificationCapability().getCount()));
jsonItemList.put(singleItem);
final Field fieldPing = test.getField("ping_median");
String pingString = "";
if (! fieldPing.isNull()) {
final double pingValue = fieldPing.doubleValue() / 1000000d;
singleItem = new JSONObject();
singleItem.put("title", labels.getString("RESULT_PING"));
pingString = String.format("%s %s", format.format(pingValue),
labels.getString("RESULT_PING_UNIT"));
singleItem.put("value", pingString);
singleItem.put("classification",
Classification.classify(Classification.THRESHOLD_PING, fieldPing.longValue(), capabilities.getClassificationCapability().getCount()));
jsonItemList.put(singleItem);
}
boolean dualSim = false;
final Field dualSimField = test.getField("dual_sim");
if (! dualSimField.isNull() && (dualSimField.toString() == "true"))
dualSim = true;
final int networkType = test.getField("network_type").intValue();
String signalString = null;
final Field signalField = test.getField("signal_strength"); // signal strength as RSSI (GSM, UMTS, Wifi, sometimes LTE)
final Field lteRsrpField = test.getField("lte_rsrp"); // signal strength as RSRP, used in LTE
if (!dualSim)
{
if (!signalField.isNull() || !lteRsrpField.isNull() )
{
if (lteRsrpField.isNull()) { // only RSSI value, output RSSI to JSON
final int signalValue = signalField.intValue();
final int[] threshold = networkType == 99 || networkType == 0 ? Classification.THRESHOLD_SIGNAL_WIFI
: Classification.THRESHOLD_SIGNAL_MOBILE;
singleItem = new JSONObject();
singleItem.put("title", labels.getString("RESULT_SIGNAL"));
signalString = signalValue + " " + labels.getString("RESULT_SIGNAL_UNIT");
singleItem.put("value", signalString);
singleItem.put("classification", Classification.classify(threshold, signalValue, capabilities.getClassificationCapability().getCount()));
}
else { // use RSRP value else (RSRP value has priority if both are available (e.g. 3G/4G-test))
final int signalValue = lteRsrpField.intValue();
final int[] threshold = Classification.THRESHOLD_SIGNAL_RSRP;
singleItem = new JSONObject();
singleItem.put("title", labels.getString("RESULT_SIGNAL_RSRP"));
signalString = signalValue + " " + labels.getString("RESULT_SIGNAL_UNIT");
singleItem.put("value", signalString);
singleItem.put("classification", Classification.classify(threshold, signalValue, capabilities.getClassificationCapability().getCount()));
}
jsonItemList.put(singleItem);
}
} //dualSim
jsonItem.put("measurement", jsonItemList);
jsonItemList = new JSONArray();
singleItem = new JSONObject();
singleItem.put("title", labels.getString("RESULT_NETWORK_TYPE"));
final String networkTypeString = Helperfunctions.getNetworkTypeName(networkType);
if (dualSim)
singleItem.put("value", labels.getString("RESULT_DUAL_SIM"));
else
singleItem.put("value", networkTypeString);
jsonItemList.put(singleItem);
if (networkType == 98 || networkType == 99) // mobile wifi or browser
{
final Field providerNameField = test.getField("provider_id_name");
if (! providerNameField.isNull())
{
singleItem = new JSONObject();
singleItem.put("title", labels.getString("RESULT_OPERATOR_NAME"));
singleItem.put("value", providerNameField.toString());
jsonItemList.put(singleItem);
}
if (networkType == 99) // mobile wifi
{
final Field ssid = test.getField("wifi_ssid");
if (! ssid.isNull())
{
singleItem = new JSONObject();
singleItem.put("title", labels.getString("RESULT_WIFI_SSID"));
singleItem.put("value", ssid.toString());
jsonItemList.put(singleItem);
}
}
}
else // mobile
{
if (!dualSim)
{
final Field operatorNameField = test.getField("network_operator_name");
if (! operatorNameField.isNull())
{
singleItem = new JSONObject();
singleItem.put("title", labels.getString("RESULT_OPERATOR_NAME"));
singleItem.put("value", operatorNameField.toString());
jsonItemList.put(singleItem);
}
final Field roamingTypeField = test.getField("roaming_type");
if (! roamingTypeField.isNull() && roamingTypeField.intValue() > 0)
{
singleItem = new JSONObject();
singleItem.put("title", labels.getString("RESULT_ROAMING"));
singleItem.put("value", Helperfunctions.getRoamingType(labels, roamingTypeField.intValue()));
jsonItemList.put(singleItem);
}
}
}
jsonItem.put("net", jsonItemList);
final Field latField = test.getField("geo_lat");
final Field longField = test.getField("geo_long");
boolean includeLocation = false;
final Field accuracyField = test.getField("geo_accuracy");
if (!(latField.isNull() || longField.isNull() || accuracyField.isNull()))
{
final double accuracy = accuracyField.doubleValue();
if (accuracy < Double.parseDouble(settings.getString("RMBT_GEO_ACCURACY_BUTTON_LIMIT")))
{
includeLocation = true;
jsonItem.put("geo_lat", latField.doubleValue());
jsonItem.put("geo_long", longField.doubleValue());
}
}
//geo location
JSONObject locationJson = TestResultDetailResource.getGeoLocation(test, settings, conn, labels);
if (locationJson != null) {
if (locationJson.has("location")) {
jsonItem.put("location", locationJson.getString("location"));
}
if (locationJson.has("motion")) {
jsonItem.put("motion", locationJson.getString("motion"));
}
}
resultList.put(jsonItem);
final Field zip_code = test.getField("zip_code");
if (! zip_code.isNull())
jsonItem.put("zip_code", zip_code.intValue());
final Field zip_code_geo = test.getField("zip_code_geo");
if (! zip_code_geo.isNull())
jsonItem.put("zip_code_geo", zip_code_geo.intValue());
String providerString = test.getField("provider_id_name").toString();
if (providerString == null)
providerString = "";
String platformString = test.getField("plattform").toString();
if (platformString == null)
platformString = "";
String modelString = test.getField("model_fullname").toString();
if (modelString == null)
modelString = "";
String mobileNetworkString = null;
final Field networkOperatorField = test.getField("network_operator");
final Field mobileProviderNameField = test.getField("mobile_provider_name");
if (! networkOperatorField.isNull())
{
if (mobileProviderNameField.isNull())
mobileNetworkString = networkOperatorField.toString();
else
mobileNetworkString = String.format("%s (%s)", mobileProviderNameField, networkOperatorField);
}
/*
RESULT_SHARE_TEXT = My Result:\nDate/time: {0}\nDownload: {1}\nUpload: {2}\nPing: {3}\n{4}Network type: {5}\n{6}{7}Platform: {8}\nModel: {9}\n{10}\n\n
RESULT_SHARE_TEXT_SIGNAL_ADD = Signal strength: {0}\n
RESULT_SHARE_TEXT_RSRP_ADD = Signal strength (RSRP): {0}\n
RESULT_SHARE_TEXT_MOBILE_ADD = Mobile network: {0}\n
RESULT_SHARE_TEXT_PROVIDER_ADD = Operator: {0}\n
*/
String shareTextField4 = "";
if (signalString != null) //info on signal strength, field 4
if (lteRsrpField.isNull()) { //add RSSI if RSRP is not available
shareTextField4 = MessageFormat.format(labels.getString("RESULT_SHARE_TEXT_SIGNAL_ADD"), signalString);
}
else { //add RSRP
shareTextField4 = MessageFormat.format(labels.getString("RESULT_SHARE_TEXT_RSRP_ADD"), signalString);
}
String shareLocation = "";
if (includeLocation && locationJson != null) {
shareLocation = MessageFormat.format(labels.getString("RESULT_SHARE_TEXT_LOCATION_ADD"),
locationJson.getString("location"));
}
String shareText;
if (dualSim)
shareText = MessageFormat.format(labels.getString("RESULT_SHARE_TEXT"),
timeString, //field 0
downloadString, //field 1
uploadString, //field 2
pingString, //field 3
shareTextField4, //contains field 4
"", //field 5
"", //field 6
labels.getString("RESULT_DUAL_SIM"), //field 7
platformString, //field 8
modelString, //field 9
//dz add location
shareLocation, //field 10
getSetting("url_open_data_prefix", lang) +
openTestUUID); //field 11
else
shareText = MessageFormat.format(labels.getString("RESULT_SHARE_TEXT"),
timeString, //field 0
downloadString, //field 1
uploadString, //field 2
pingString, //field 3
shareTextField4, //contains field 4
networkTypeString, //field 5
providerString.isEmpty() ? "" : MessageFormat.format(labels.getString("RESULT_SHARE_TEXT_PROVIDER_ADD"),
providerString), //field 6
mobileNetworkString == null ? "" : MessageFormat.format(labels.getString("RESULT_SHARE_TEXT_MOBILE_ADD"),
mobileNetworkString), //field 7
platformString, //field 8
modelString, //field 9
//dz add location
shareLocation, //field 10
getSetting("url_open_data_prefix", lang) +
openTestUUID); //field 11
jsonItem.put("share_text", shareText);
final String shareSubject = MessageFormat.format(labels.getString("RESULT_SHARE_SUBJECT"),
timeString //field 0
);
jsonItem.put("share_subject", shareSubject);
jsonItem.put("network_type", networkType);
if (resultList.length() == 0)
errorList.addError("ERROR_DB_GET_TESTRESULT");
// errorList.addError(MessageFormat.format(labels.getString("ERROR_DB_GET_CLIENT"),
// new Object[] {uuid}));
answer.put("testresult", resultList);
}
else
errorList.addError("ERROR_REQUEST_NO_UUID");
}
else
errorList.addError("ERROR_DB_CONNECTION");
}
catch (final JSONException e)
{
errorList.addError("ERROR_REQUEST_JSON");
System.out.println("Error parsing JSDON Data " + e.toString());
}
else
errorList.addErrorString("Expected request is missing.");
try
{
answer.putOpt("error", errorList.getList());
}
catch (final JSONException e)
{
System.out.println("Error saving ErrorList: " + e.toString());
}
answerString = answer.toString();
long elapsedTime = System.currentTimeMillis() - startTime;
System.out.println(MessageFormat.format(labels.getString("NEW_TESTRESULT_SUCCESS"), clientIpRaw, Long.toString(elapsedTime)));
return answerString;
}
@Get("json")
public String retrieve(final String entity)
{
return request(entity);
}
}