diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java index 20b4833d56..d686ff5115 100755 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java @@ -97,10 +97,7 @@ import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509Certificate; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.List; +import java.util.*; import java.util.concurrent.TimeUnit; public class CertificateGenerator { @@ -798,8 +795,16 @@ public class CertificateGenerator { BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis()); - X500Name issuerName = new X500Name(certCA.getSubjectDN().getName()); - + //Reversing the order of components of the subject DN due to Nginx not verifying the client certificate + //generated by Java using this subject DN. + //Ref: https://stackoverflow.com/questions/33769978 & engineering mail SCEP implementation for Android + String[] dnParts = certCA.getSubjectDN().getName().split(","); + StringJoiner joiner = new StringJoiner(","); + for (int i = (dnParts.length - 1); i >= 0; i--) { + joiner.add(dnParts[i]); + } + String subjectDn = joiner.toString(); + X500Name issuerName = new X500Name(subjectDn); String commonName = certificationRequest.getSubject().getRDNs(BCStyle.CN)[0].getFirst() .getValue().toString(); X500Name subjectName = new X500Name("O=" + commonName + "O=AndroidDevice,CN=" + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/pom.xml b/components/device-mgt/org.wso2.carbon.device.mgt.api/pom.xml index 7077d97672..8e36f72c2f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/pom.xml +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/pom.xml @@ -455,5 +455,25 @@ io.entgra.device.mgt.core.apimgt.analytics.extension provided + + com.google.api-client + google-api-client + 2.2.0 + + + com.google.apis + google-api-services-sheets + v4-rev539-1.25.0 + + + com.google.http-client + google-http-client-jackson2 + 1.43.1 + + + net.sf.ehcache + ehcache-terracotta + 2.1.1 + \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceImpl.java index ed57498164..34b4f3bc83 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceImpl.java @@ -18,6 +18,12 @@ */ package org.wso2.carbon.device.mgt.jaxrs.service.impl; +import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; +import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; +import com.google.api.client.json.jackson2.JacksonFactory; +import com.google.api.services.sheets.v4.Sheets; +import com.google.api.services.sheets.v4.SheetsScopes; +import com.google.api.services.sheets.v4.model.ValueRange; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; @@ -54,23 +60,19 @@ import org.wso2.carbon.policy.mgt.common.PolicyManagementException; import org.wso2.carbon.user.api.UserStoreException; import javax.validation.Valid; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.QueryParam; +import javax.ws.rs.*; import javax.ws.rs.core.Response; +import java.io.FileInputStream; +import java.io.IOException; import java.rmi.RemoteException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.security.GeneralSecurityException; +import java.util.*; @Path("/device/agent") public class DeviceAgentServiceImpl implements DeviceAgentService { - private static final Log log = LogFactory.getLog(DeviceAgentServiceImpl.class); + static final Log log = LogFactory.getLog(DeviceAgentServiceImpl.class); private static final String POLICY_MONITOR = "POLICY_MONITOR"; + @POST @Path("/enroll") @Override @@ -127,7 +129,7 @@ public class DeviceAgentServiceImpl implements DeviceAgentService { return Response.status(Response.Status.OK).build(); } else { return Response.status(Response.Status.NO_CONTENT).entity(type + " device that carries id '" + id + - "' has not been dis-enrolled").build(); + "' has not been dis-enrolled").build(); } } catch (DeviceManagementException e) { String msg = "Error occurred while enrolling the device, which carries the id '" + id + "'"; @@ -163,7 +165,7 @@ public class DeviceAgentServiceImpl implements DeviceAgentService { log.error(errorMessage); return Response.status(Response.Status.NOT_FOUND).entity(errorMessage).build(); } - if (device.getEnrolmentInfo().getStatus() == EnrolmentInfo.Status.ACTIVE ) { + if (device.getEnrolmentInfo().getStatus() == EnrolmentInfo.Status.ACTIVE) { DeviceAccessAuthorizationService deviceAccessAuthorizationService = DeviceMgtAPIUtils.getDeviceAccessAuthorizationService(); boolean status; @@ -179,25 +181,25 @@ public class DeviceAgentServiceImpl implements DeviceAgentService { return Response.status(Response.Status.UNAUTHORIZED).build(); } } - if(updateDevice.getEnrolmentInfo() != null) { + if (updateDevice.getEnrolmentInfo() != null) { device.getEnrolmentInfo().setDateOfLastUpdate(System.currentTimeMillis()); device.setEnrolmentInfo(device.getEnrolmentInfo()); } device.getEnrolmentInfo().setOwner(DeviceMgtAPIUtils.getAuthenticatedUser()); - if(updateDevice.getDeviceInfo() != null) { + if (updateDevice.getDeviceInfo() != null) { device.setDeviceInfo(updateDevice.getDeviceInfo()); } device.setDeviceIdentifier(id); - if(updateDevice.getDescription() != null) { + if (updateDevice.getDescription() != null) { device.setDescription(updateDevice.getDescription()); } - if(updateDevice.getName() != null) { + if (updateDevice.getName() != null) { device.setName(updateDevice.getName()); } - if(updateDevice.getFeatures() != null) { + if (updateDevice.getFeatures() != null) { device.setFeatures(updateDevice.getFeatures()); } - if(updateDevice.getProperties() != null) { + if (updateDevice.getProperties() != null) { device.setProperties(updateDevice.getProperties()); } boolean result; @@ -237,7 +239,7 @@ public class DeviceAgentServiceImpl implements DeviceAgentService { return Response.status(Response.Status.UNAUTHORIZED).entity(msg).build(); } } - Object metaData[] = new Object[1]; + Object[] metaData = new Object[1]; metaData[0] = deviceId; EventAttributeList eventAttributeList = DeviceMgtAPIUtils.getDynamicEventCache().get(type); if (eventAttributeList == null) { @@ -281,7 +283,7 @@ public class DeviceAgentServiceImpl implements DeviceAgentService { // , PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain()) // , Constants.DEFAULT_STREAM_VERSION, metaData // , null, payloadData)) { - return Response.status(Response.Status.OK).build(); + return Response.status(Response.Status.OK).build(); // } else { // String msg = "Error occurred while publishing the event."; // return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); @@ -337,7 +339,7 @@ public class DeviceAgentServiceImpl implements DeviceAgentService { return Response.status(Response.Status.UNAUTHORIZED).entity(msg).build(); } } - Object metaData[] = new Object[1]; + Object[] metaData = new Object[1]; metaData[0] = deviceId; EventAttributeList eventAttributeList = DeviceMgtAPIUtils.getDynamicEventCache().get(type); if (eventAttributeList == null) { @@ -382,7 +384,7 @@ public class DeviceAgentServiceImpl implements DeviceAgentService { // , PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain()) // , Constants.DEFAULT_STREAM_VERSION, metaData // , null, payloadData)) { - return Response.status(Response.Status.OK).build(); + return Response.status(Response.Status.OK).build(); // } else { // String msg = "Error occurred while publishing the event."; // return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); @@ -433,23 +435,63 @@ public class DeviceAgentServiceImpl implements DeviceAgentService { log.error(msg); return Response.status(Response.Status.NO_CONTENT).entity(msg).build(); } + long startTime = System.currentTimeMillis(); // Record the start time + List operations = DeviceMgtAPIUtils.getDeviceManagementService().getPendingOperations( deviceIdentifier); OperationList operationsList = new OperationList(); operationsList.setList(operations); operationsList.setCount(operations.size()); + + long endTime = System.currentTimeMillis(); // Record the end time + long responseTime = endTime - startTime; // Calculate the response time + + // Save the response time to Google Spreadsheet + Sheets sheetsService = createSheetsService(); // Create Sheets service using loaded credentials + String spreadsheetId = "1OZCS5NRwwSum9ai3ra4lABtU0UGW-9yLYgZk-aQfxpw"; + + // Create the values to be written + List> values = Collections.singletonList( + Arrays.asList(deviceId, String.valueOf(responseTime)) + ); + + // Create the value range + ValueRange body = new ValueRange().setValues(values); + + // Write the values to the spreadsheet + sheetsService.spreadsheets().values() + .append(spreadsheetId, "Sheet1", body) + .setValueInputOption("USER_ENTERED") + .execute(); return Response.status(Response.Status.OK).entity(operationsList).build(); } catch (OperationManagementException e) { String errorMessage = "Issue in retrieving operation management service instance"; log.error(errorMessage, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build(); } catch (DeviceManagementException e) { - String errorMessage = "Issue in retrieving deivce management service instance"; + String errorMessage = "Issue in retrieving device management service instance"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build(); + } catch (IOException e) { + // Handle any errors occurred while writing to the spreadsheet + String errorMessage = "Error writing response time to Google Spreadsheet"; log.error(errorMessage, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build(); } } + private Sheets createSheetsService() throws IOException { + GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("components/device-mgt/org.wso2.carbon.device.mgt.api/target/apicall-382608-48aa6a62800d.json")) + .createScoped(Collections.singleton(SheetsScopes.SPREADSHEETS)); + try { + return new Sheets.Builder(GoogleNetHttpTransport.newTrustedTransport(), JacksonFactory.getDefaultInstance(), credential) + .setApplicationName("ApiCall") + .build(); + } catch (GeneralSecurityException e) { + throw new RuntimeException(e); + } + } + @GET @Path("/next-pending/operation/{type}/{id}") public Response getNextPendingOperation(@PathParam("type") String type, @PathParam("id") String deviceId) { @@ -530,14 +572,14 @@ public class DeviceAgentServiceImpl implements DeviceAgentService { @PUT @Path("/properties/{type}/{id}") public Response updateDeviceProperties(@PathParam("type") String type, @PathParam("id") String deviceId, - @Valid List properties) { + @Valid List properties) { try { if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) { String errorMessage = "Device type is invalid"; log.error(errorMessage); return Response.status(Response.Status.BAD_REQUEST).build(); } - if(properties == null) { + if (properties == null) { String errorMessage = "Properties cannot be empty"; log.error(errorMessage); return Response.status(Response.Status.BAD_REQUEST).build(); @@ -549,7 +591,7 @@ public class DeviceAgentServiceImpl implements DeviceAgentService { return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } - if (DeviceMgtAPIUtils.getDeviceManagementService().updateProperties(deviceIdentifier, properties)){ + if (DeviceMgtAPIUtils.getDeviceManagementService().updateProperties(deviceIdentifier, properties)) { return Response.status(Response.Status.ACCEPTED).entity("Device properties updated.").build(); } else { return Response.status(Response.Status.NOT_ACCEPTABLE).entity("Device properties not updated.").build(); @@ -595,7 +637,7 @@ public class DeviceAgentServiceImpl implements DeviceAgentService { } private static List getComplianceFeatures(Object compliancePayload) throws - PolicyComplianceException { + PolicyComplianceException { String compliancePayloadString = new Gson().toJson(compliancePayload); if (compliancePayload == null) { return null; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/PendingOperationsResourceResponseTime.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/PendingOperationsResourceResponseTime.java new file mode 100644 index 0000000000..1b8a7d2a53 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/PendingOperationsResourceResponseTime.java @@ -0,0 +1,102 @@ +//package org.wso2.carbon.device.mgt.jaxrs.service.impl; +// +//import com.google.api.client.auth.oauth2.Credential; +//import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; +//import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; +//import com.google.api.client.googleapis.json.GoogleJsonResponseException; +//import com.google.api.client.http.HttpTransport; +//import com.google.api.client.json.JsonFactory; +//import com.google.api.client.json.jackson2.JacksonFactory; +//import com.google.api.services.sheets.v4.Sheets; +//import com.google.api.services.sheets.v4.SheetsScopes; +//import com.google.api.services.sheets.v4.model.AppendValuesResponse; +//import com.google.api.services.sheets.v4.model.ValueRange; +// +//import javax.annotation.PreDestroy; +//import javax.ws.rs.GET; +//import javax.ws.rs.Path; +//import javax.ws.rs.PathParam; +//import javax.ws.rs.Produces; +//import javax.ws.rs.client.Client; +//import javax.ws.rs.client.ClientBuilder; +//import javax.ws.rs.core.MediaType; +//import javax.ws.rs.core.Response; +//import java.io.IOException; +//import java.security.GeneralSecurityException; +//import java.util.Collections; +// +//import static org.wso2.carbon.device.mgt.jaxrs.service.impl.DeviceAgentServiceImpl.log; +// +//@Path("/pending/operations/{type}/{id}") +//public class PendingOperationsResourceResponseTime { +// +// private final Client client; +// private final Sheets sheetsService; +// private final String spreadsheetId; +// private final String sheetName; +// +// public PendingOperationsResourceResponseTime() throws IOException, GeneralSecurityException { +// this.client = ClientBuilder.newClient(); +// +// // Build the credentials object using Google OAuth 2.0 authentication +// Credential credential = GoogleCredential.getApplicationDefault().createScoped(Collections.singleton(SheetsScopes.SPREADSHEETS)); +// HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport(); +// JsonFactory jsonFactory = JacksonFactory.getDefaultInstance(); +// +// // Create a Sheets service object to interact with the Google Sheets API +// this.sheetsService = new Sheets.Builder(httpTransport, jsonFactory, credential) +// .setApplicationName("ApiCall") +// .build(); +// +// // Set the spreadsheet ID and sheet name to write the results to +// this.spreadsheetId = "1OZCS5NRwwSum9ai3ra4lABtU0UGW-9yLYgZk-aQfxpw"; +// this.sheetName = "Sheet1"; +// } +// +// @GET +// @Produces(MediaType.APPLICATION_JSON) +// public Response getPendingOperations(@PathParam("type") String type, @PathParam("id") String deviceId) { +// long startTime = System.currentTimeMillis(); +// Response apiResponse = client.target("http://example.com/api/pending-operations") +// .queryParam("type", type) +// .queryParam("deviceId", deviceId) +// .request(MediaType.APPLICATION_JSON) +// .get(); +// long endTime = System.currentTimeMillis(); +// long responseTime = endTime - startTime; +// +// // log the response time +// log.info("API response time: {} ms"); +// +// // write the results to Google Sheets +// try { +// writeResultsToSheet(startTime, endTime, responseTime); +// } catch (IOException e) { +// log.error("Error writing results to Google Sheets", e); +// } +// +// return apiResponse; +// } +// +// @PreDestroy +// public void cleanup() { +// client.close(); +// } +// +// private void writeResultsToSheet(long startTime, long endTime, long responseTime) throws IOException { +// // create a ValueRange object with the data to write +// ValueRange valueRange = new ValueRange().setValues(Collections.singletonList( +// Collections.singletonList(startTime + "," + endTime + "," + responseTime))); +// +// // append the data to the Google Sheet +// try { +// AppendValuesResponse response = sheetsService.spreadsheets().values() +// .append(spreadsheetId, sheetName, valueRange) +// .setValueInputOption("RAW") +// .execute(); +// log.info("Data written to Google Sheets: {}"); +// } catch (GoogleJsonResponseException e) { +// log.error("Error writing data to Google Sheets: {}"); +// } +// } +//} \ No newline at end of file