From b90766b5a4e2946133235eb430590a4712c544b0 Mon Sep 17 00:00:00 2001 From: lasanthaDLPDS Date: Wed, 16 Jan 2019 08:08:27 +0530 Subject: [PATCH] Add enrollment notification sending feature --- .../DeviceEnrollmentInfoNotification.java | 94 ++++++++++ .../device/mgt/common/DeviceNotification.java | 53 ++++++ .../common/DevicePropertyNotification.java | 46 +++++ .../EnrollmentNotificationConfiguration.java | 89 ++++++++++ .../notification/EnrollmentNotifier.java | 35 ++++ .../EnrollmentNotifierException.java | 48 +++++ .../mgt/core/DeviceManagementConstants.java | 1 + .../core/config/DeviceManagementConfig.java | 12 ++ .../device/mgt/core/dao/EnrollmentDAO.java | 2 +- .../mgt/core/dao/impl/EnrollmentDAOImpl.java | 16 +- .../DeviceManagementProviderServiceImpl.java | 168 +++++++++++++++++- .../src/test/resources/mssql-testng.xml | 2 +- .../src/test/resources/mysql-testng.xml | 2 +- .../src/test/resources/oracle-testng.xml | 2 +- .../src/test/resources/postgre-testng.xml | 2 +- .../src/main/resources/conf/cdm-config.xml | 6 + 16 files changed, 560 insertions(+), 18 deletions(-) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceEnrollmentInfoNotification.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceNotification.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DevicePropertyNotification.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/enrollment/notification/EnrollmentNotificationConfiguration.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/enrollment/notification/EnrollmentNotifier.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/enrollment/notification/EnrollmentNotifierException.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceEnrollmentInfoNotification.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceEnrollmentInfoNotification.java new file mode 100644 index 00000000000..f4b10218a1c --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceEnrollmentInfoNotification.java @@ -0,0 +1,94 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you 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 org.wso2.carbon.device.mgt.common; + +public class DeviceEnrollmentInfoNotification { + + /*** + * Enrollment Id + */ + private int id; + /*** + * Enrollment timestamp + */ + private Long dateOfEnrolment; + /*** + * Last updated timestamp + */ + private Long dateOfLastUpdate; + /*** + * Ownership of the device + */ + private String ownership; + /*** + * Status of the device + */ + private String status; + /*** + * Owner of the device + */ + private String owner; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Long getDateOfEnrolment() { + return dateOfEnrolment; + } + + public void setDateOfEnrolment(Long dateOfEnrolment) { + this.dateOfEnrolment = dateOfEnrolment; + } + + public Long getDateOfLastUpdate() { + return dateOfLastUpdate; + } + + public void setDateOfLastUpdate(Long dateOfLastUpdate) { + this.dateOfLastUpdate = dateOfLastUpdate; + } + + public String getOwnership() { + return ownership; + } + + public void setOwnership(String ownership) { + this.ownership = ownership; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceNotification.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceNotification.java new file mode 100644 index 00000000000..46238b9a53c --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceNotification.java @@ -0,0 +1,53 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you 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 org.wso2.carbon.device.mgt.common; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "device") +public class DeviceNotification { + + + @XmlAttribute(name = "id") + private int deviceId; + @XmlElement(name = "name") + private String deviceName; + @XmlElement(name = "type") + private String deviceType; + @XmlElement(name = "description") + private String description; + @XmlElement(name = "properties") + private DevicePropertyNotification properties; + @XmlElement(name = "enrollment_info") + private DeviceEnrollmentInfoNotification enrollmentInfo; + + public DeviceNotification(){} + + public DeviceNotification(int deviceId, String deviceName, String deviceType, String description, + DevicePropertyNotification devicePropertyNotification, + DeviceEnrollmentInfoNotification deviceEnrollmentInfoNotification) { + this.deviceId = deviceId; + this.deviceName = deviceName; + this.deviceType = deviceType; + this.description = description; + this.properties = devicePropertyNotification; + this.enrollmentInfo = deviceEnrollmentInfoNotification; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DevicePropertyNotification.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DevicePropertyNotification.java new file mode 100644 index 00000000000..8a1685ce3f5 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DevicePropertyNotification.java @@ -0,0 +1,46 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you 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 org.wso2.carbon.device.mgt.common; + +public class DevicePropertyNotification { + + /*** + * Serial number + */ + private String serial; + /*** + * IMEI number + */ + private String imei; + + public String getSerial() { + return serial; + } + + public void setSerial(String serial) { + this.serial = serial; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/enrollment/notification/EnrollmentNotificationConfiguration.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/enrollment/notification/EnrollmentNotificationConfiguration.java new file mode 100644 index 00000000000..5937c92b99f --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/enrollment/notification/EnrollmentNotificationConfiguration.java @@ -0,0 +1,89 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you 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 org.wso2.carbon.device.mgt.common.enrollment.notification; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * This class represents the information related to Enrollment Configuration configuration. + */ +@XmlRootElement(name = "EnrolmentNotificationConfiguration") +public class EnrollmentNotificationConfiguration { + + private boolean notifyThroughExtension; + private boolean enabled; + private String extensionClass; + private String notyfyingInternalHost; + + /** + * Enrollment Notification enabled + * + * @return If it is required to send notification for each enrollment, returns true otherwise returns false + */ + @XmlElement(name = "Enabled", required = true) + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public void setNotifyThroughExtension(boolean notifyThroughExtension) { + this.notifyThroughExtension = notifyThroughExtension; + } + + /** + * Enable notifying the enrollment through extension + * + * @return IF notifications are sending through the extension, returns true otherwise returns false + */ + @XmlElement(name = "NotifyThroughExtension", required = true) + public boolean getNotifyThroughExtension() { + return notifyThroughExtension; + } + + /** + * Extension Class + * + * @return extension full class path is returned + */ + @XmlElement(name = "ExtensionClass", required = true) + public String getExtensionClass() { + return extensionClass; + } + + public void setExtensionClass(String extensionClass) { + this.extensionClass = extensionClass; + } + + /** + * Extension Class + * + * @return extension full class path is returned + */ + @XmlElement(name = "NotifyingInternalHost", required = true) + public String getNotyfyingInternalHost() { + return notyfyingInternalHost; + } + + public void setNotyfyingInternalHost(String notyfyingInternalHost) { + this.notyfyingInternalHost = notyfyingInternalHost; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/enrollment/notification/EnrollmentNotifier.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/enrollment/notification/EnrollmentNotifier.java new file mode 100644 index 00000000000..4c94598c331 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/enrollment/notification/EnrollmentNotifier.java @@ -0,0 +1,35 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you 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 org.wso2.carbon.device.mgt.common.enrollment.notification; + +import org.wso2.carbon.device.mgt.common.Device; + +/*** + * + */ +public interface EnrollmentNotifier { + + /*** + * notify method could be used to notify an enrollment of IoTS to a desired endpoint. This method could + * be invoked when a successful new enrollment completes. + * + * @throws EnrollmentNotifierException, if an error occurs while notify the enrollment to a defined end point + * + */ + void notify(Device device) throws EnrollmentNotifierException; +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/enrollment/notification/EnrollmentNotifierException.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/enrollment/notification/EnrollmentNotifierException.java new file mode 100644 index 00000000000..1df3e800921 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/enrollment/notification/EnrollmentNotifierException.java @@ -0,0 +1,48 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you 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 org.wso2.carbon.device.mgt.common.enrollment.notification; + +/*** + * The EnrollmentNotifierException wraps all unchecked standard Java exception and this could be thrown if error occurs + * while notifying enrollment for defined endpoint and also if and only if enrollment notification is enabled. + * + */ +public class EnrollmentNotifierException extends Exception { + + private static final long serialVersionUID = -5980273112833902095L; + + public EnrollmentNotifierException(String msg, Exception nestedEx) { + super(msg, nestedEx); + } + + public EnrollmentNotifierException(String message, Throwable cause) { + super(message, cause); + } + + public EnrollmentNotifierException(String msg) { + super(msg); + } + + public EnrollmentNotifierException() { + super(); + } + + public EnrollmentNotifierException(Throwable cause) { + super(cause); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java index a7961c41fd1..57b00cb5a8c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java @@ -25,6 +25,7 @@ public final class DeviceManagementConstants { public static final String DM_CACHE_MANAGER = "DM_CACHE_MANAGER"; public static final String DEVICE_CACHE = "DEVICE_CACHE"; + public static final String ENROLLMENT_NOTIFICATION_API_ENDPOINT = "/api/device-mgt/enrollment-notification"; public static final class Common { private Common() { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/DeviceManagementConfig.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/DeviceManagementConfig.java index df57f65af44..456de2f2d47 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/DeviceManagementConfig.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/DeviceManagementConfig.java @@ -17,6 +17,7 @@ */ package org.wso2.carbon.device.mgt.core.config; +import org.wso2.carbon.device.mgt.common.enrollment.notification.EnrollmentNotificationConfiguration; import org.wso2.carbon.device.mgt.core.config.analytics.OperationAnalyticsConfiguration; import org.wso2.carbon.device.mgt.core.config.archival.ArchivalConfiguration; import org.wso2.carbon.device.mgt.core.config.cache.CertificateCacheConfiguration; @@ -58,6 +59,7 @@ public final class DeviceManagementConfig { private String defaultGroupsConfiguration; private RemoteSessionConfiguration remoteSessionConfiguration; private ArchivalConfiguration archivalConfiguration; + private EnrollmentNotificationConfiguration enrollmentNotificationConfiguration; @XmlElement(name = "ManagementRepository", required = true) @@ -203,5 +205,15 @@ public final class DeviceManagementConfig { public void setRemoteSessionConfiguration(RemoteSessionConfiguration remoteSessionConfiguration) { this.remoteSessionConfiguration = remoteSessionConfiguration; } + + @XmlElement(name = "EnrolmentNotificationConfiguration", required = true) + public EnrollmentNotificationConfiguration getEnrollmentNotificationConfiguration() { + return enrollmentNotificationConfiguration; + } + + public void setEnrollmentNotificationConfiguration( + EnrollmentNotificationConfiguration enrollmentNotificationConfiguration) { + this.enrollmentNotificationConfiguration = enrollmentNotificationConfiguration; + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/EnrollmentDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/EnrollmentDAO.java index 21cc243abe8..843e8df6464 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/EnrollmentDAO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/EnrollmentDAO.java @@ -25,7 +25,7 @@ import java.util.List; public interface EnrollmentDAO { - int addEnrollment(int deviceId, EnrolmentInfo enrolmentInfo, int tenantId) throws DeviceManagementDAOException; + EnrolmentInfo addEnrollment(int deviceId, EnrolmentInfo enrolmentInfo, int tenantId) throws DeviceManagementDAOException; int updateEnrollment(int deviceId, EnrolmentInfo enrolmentInfo, int tenantId) throws DeviceManagementDAOException; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/EnrollmentDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/EnrollmentDAOImpl.java index b7a4086d0eb..89e20dc2421 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/EnrollmentDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/EnrollmentDAOImpl.java @@ -36,31 +36,35 @@ import java.util.List; public class EnrollmentDAOImpl implements EnrollmentDAO { @Override - public int addEnrollment(int deviceId, EnrolmentInfo enrolmentInfo, + public EnrolmentInfo addEnrollment(int deviceId, EnrolmentInfo enrolmentInfo, int tenantId) throws DeviceManagementDAOException { Connection conn; PreparedStatement stmt = null; ResultSet rs = null; - int enrolmentId = -1; try { conn = this.getConnection(); String sql = "INSERT INTO DM_ENROLMENT(DEVICE_ID, OWNER, OWNERSHIP, STATUS, " + "DATE_OF_ENROLMENT, DATE_OF_LAST_UPDATE, TENANT_ID) VALUES(?, ?, ?, ?, ?, ?, ?)"; stmt = conn.prepareStatement(sql, new String[] {"id"}); + Timestamp enrollmentTime = new Timestamp(new Date().getTime()); stmt.setInt(1, deviceId); stmt.setString(2, enrolmentInfo.getOwner()); stmt.setString(3, enrolmentInfo.getOwnership().toString()); stmt.setString(4, enrolmentInfo.getStatus().toString()); - stmt.setTimestamp(5, new Timestamp(new Date().getTime())); - stmt.setTimestamp(6, new Timestamp(new Date().getTime())); + stmt.setTimestamp(5, enrollmentTime); + stmt.setTimestamp(6, enrollmentTime); stmt.setInt(7, tenantId); stmt.execute(); rs = stmt.getGeneratedKeys(); if (rs.next()) { - enrolmentId = rs.getInt(1); + int enrolmentId = rs.getInt(1); + enrolmentInfo.setId(enrolmentId); + enrolmentInfo.setDateOfEnrolment(enrollmentTime.getTime()); + enrolmentInfo.setDateOfLastUpdate(enrollmentTime.getTime()); + return enrolmentInfo; } - return enrolmentId; + return null; } catch (SQLException e) { throw new DeviceManagementDAOException("Error occurred while adding enrolment configuration", e); } finally { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java index a22242796c7..923ed22fb19 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java @@ -20,15 +20,25 @@ package org.wso2.carbon.device.mgt.core.service; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.protocol.HTTP; import org.wso2.carbon.CarbonConstants; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException; import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceEnrollmentInfoNotification; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.common.DeviceManager; import org.wso2.carbon.device.mgt.common.DeviceNotFoundException; +import org.wso2.carbon.device.mgt.common.DeviceNotification; +import org.wso2.carbon.device.mgt.common.DevicePropertyNotification; import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.FeatureManager; import org.wso2.carbon.device.mgt.common.InitialOperationConfig; @@ -43,6 +53,9 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManageme import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo; import org.wso2.carbon.device.mgt.common.device.details.DeviceLocation; +import org.wso2.carbon.device.mgt.common.enrollment.notification.EnrollmentNotificationConfiguration; +import org.wso2.carbon.device.mgt.common.enrollment.notification.EnrollmentNotifier; +import org.wso2.carbon.device.mgt.common.enrollment.notification.EnrollmentNotifierException; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants; import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyExistException; @@ -61,6 +74,8 @@ import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService; import org.wso2.carbon.device.mgt.core.DeviceManagementConstants; import org.wso2.carbon.device.mgt.core.DeviceManagementPluginRepository; import org.wso2.carbon.device.mgt.core.cache.impl.DeviceCacheManagerImpl; +import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager; +import org.wso2.carbon.device.mgt.core.config.DeviceManagementConfig; import org.wso2.carbon.device.mgt.core.dao.ApplicationDAO; import org.wso2.carbon.device.mgt.core.dao.DeviceDAO; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; @@ -88,6 +103,11 @@ import org.wso2.carbon.email.sender.core.TypedValue; import org.wso2.carbon.email.sender.core.service.EmailSenderService; import org.wso2.carbon.user.api.UserStoreException; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import java.io.IOException; +import java.io.StringWriter; import java.sql.SQLException; import java.util.ArrayList; import java.util.Calendar; @@ -206,6 +226,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv if (enrolmentInfo.equals(newEnrolmentInfo)) { device.setId(existingDevice.getId()); device.getEnrolmentInfo().setDateOfEnrolment(enrolmentInfo.getDateOfEnrolment()); + device.getEnrolmentInfo().setDateOfLastUpdate(enrolmentInfo.getDateOfLastUpdate()); device.getEnrolmentInfo().setId(enrolmentInfo.getId()); this.modifyEnrollment(device); status = true; @@ -213,7 +234,8 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv } } if (!status) { - int enrolmentId, updateStatus = 0; + int updateStatus = 0; + EnrolmentInfo enrollment; try { //Remove the existing enrollment DeviceManagementDAOFactory.beginTransaction(); @@ -223,12 +245,20 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv } if ((updateStatus > 0) || EnrolmentInfo.Status.REMOVED. equals(existingEnrolmentInfo.getStatus())) { - enrolmentId = enrollmentDAO. + enrollment = enrollmentDAO. addEnrollment(existingDevice.getId(), newEnrolmentInfo, tenantId); + if (enrollment == null ){ + DeviceManagementDAOFactory.rollbackTransaction(); + throw new DeviceManagementException( + "Enrollment data persistence is failed in a re-enrollment. Device id : " + + existingDevice.getId() + " Device Identifier: " + device + .getDeviceIdentifier()); + } + device.setEnrolmentInfo(enrollment); DeviceManagementDAOFactory.commitTransaction(); this.removeDeviceFromCache(deviceIdentifier); if (log.isDebugEnabled()) { - log.debug("An enrolment is successfully added with the id '" + enrolmentId + + log.debug("An enrolment is successfully added with the id '" + enrollment.getId() + "' associated with " + "the device identified by key '" + device.getDeviceIdentifier() + "', which belongs to " + "platform '" + device.getType() + " upon the user '" + device.getEnrolmentInfo().getOwner() + @@ -254,13 +284,20 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv } } } else { - int enrolmentId; + EnrolmentInfo enrollment; try { DeviceManagementDAOFactory.beginTransaction(); DeviceType type = deviceTypeDAO.getDeviceType(device.getType(), tenantId); if (type != null) { int deviceId = deviceDAO.addDevice(type.getId(), device, tenantId); - enrolmentId = enrollmentDAO.addEnrollment(deviceId, device.getEnrolmentInfo(), tenantId); + enrollment = enrollmentDAO.addEnrollment(deviceId, device.getEnrolmentInfo(), tenantId); + if (enrollment == null ){ + DeviceManagementDAOFactory.rollbackTransaction(); + throw new DeviceManagementException( + "Enrollment data persistence is failed in a new enrollment. Device id: " + deviceId + + " Device Identifier: " + device.getDeviceIdentifier()); + } + device.setEnrolmentInfo(enrollment); DeviceManagementDAOFactory.commitTransaction(); } else { DeviceManagementDAOFactory.rollbackTransaction(); @@ -287,17 +324,17 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv } if (log.isDebugEnabled()) { - log.debug("An enrolment is successfully created with the id '" + enrolmentId + "' associated with " + + log.debug("An enrolment is successfully created with the id '" + enrollment.getId() + "' associated with " + "the device identified by key '" + device.getDeviceIdentifier() + "', which belongs to " + "platform '" + device.getType() + " upon the user '" + device.getEnrolmentInfo().getOwner() + "'"); } status = true; } - if (status) { addDeviceToGroups(deviceIdentifier, device.getEnrolmentInfo().getOwnership()); addInitialOperations(deviceIdentifier, device.getType()); + sendNotification(device); } extractDeviceLocationToUpdate(device); return status; @@ -2705,4 +2742,121 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv } } + /*** + * + *

+ * If the device enrollment is succeeded and the enrollment notification sending is enabled, this method executes. + * If it is configured to send enrollment notification by using the extension, initiate the instance from + * configured instance class and execute the notify method to send enrollment notification. + *

+ * + *

+ * In default, if it is enabled the enrollment notification sending and disabled the notifying through extension, + * it uses pre-defined API to send enrollment notification. In that case, invoke the + * /api/device-mgt/enrollment-notification API with the constructed payload. + *

+ * @param device {@link Device} object + */ + private void sendNotification(Device device) { + DeviceManagementConfig config = DeviceConfigurationManager.getInstance().getDeviceManagementConfig(); + EnrollmentNotificationConfiguration enrollmentNotificationConfiguration = config + .getEnrollmentNotificationConfiguration(); + try { + if (enrollmentNotificationConfiguration != null && enrollmentNotificationConfiguration.isEnabled()) { + if (enrollmentNotificationConfiguration.getNotifyThroughExtension()) { + Class clz = Class.forName(enrollmentNotificationConfiguration.getExtensionClass()); + EnrollmentNotifier enrollmentNotifier = (EnrollmentNotifier) clz.newInstance(); + enrollmentNotifier.notify(device); + } else { + String internalServerAddr = enrollmentNotificationConfiguration.getNotyfyingInternalHost(); + if (internalServerAddr == null) { + internalServerAddr = "https://localhost:8243"; + } + invokeApi(device, internalServerAddr); + } + } else { + if (log.isDebugEnabled()) { + log.debug( + "Either Enrollment Notification Configuration is disabled or not defined in the cdm-config.xml"); + } + } + } catch (ClassNotFoundException e) { + log.error("Extension class cannot be located", e); + } catch (IllegalAccessException e) { + log.error("Can't access the class or its nullary constructor is not accessible.", e); + } catch (InstantiationException e) { + log.error("Extension class instantiation is failed", e); + } catch (EnrollmentNotifierException e) { + log.error("Error occured while sending enrollment notification." + e); + } + } + + private void invokeApi(Device device, String internalServerAddr) throws EnrollmentNotifierException { + try (CloseableHttpClient client = HttpClients.createDefault()) { + HttpPost apiEndpoint = new HttpPost( + internalServerAddr + DeviceManagementConstants.ENROLLMENT_NOTIFICATION_API_ENDPOINT); + apiEndpoint.setHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_XML.toString()); + apiEndpoint.setEntity(constructEnrollmentNotificationPayload(device)); + HttpResponse response = client.execute(apiEndpoint); + if (response != null) { + log.info("Enrollment Notification is sent through a configured API. Response code: " + response + .getStatusLine().getStatusCode()); + } else { + log.error("Response is 'NUll' for the Enrollment notification sending API call."); + } + } catch (IOException e) { + throw new EnrollmentNotifierException("Error occured when invoking API. API endpoint: " + internalServerAddr + + DeviceManagementConstants.ENROLLMENT_NOTIFICATION_API_ENDPOINT, e); + } + } + + /*** + * + * Convert device object into XML string and construct {@link StringEntity} object and returns. + *

+ * First create {@link JAXBContext} and thereafter create {@link Marshaller} by usig created {@link JAXBContext}. + * Then enable formatting and get the converted xml string output of {@link Device}. + *

+ * + * @param device {@link Device} object + * @return {@link StringEntity} + * @throws EnrollmentNotifierException, if error occured while converting {@link Device} object into XML sting + */ + private static StringEntity constructEnrollmentNotificationPayload(Device device) + throws EnrollmentNotifierException { + try { + DevicePropertyNotification devicePropertyNotification = new DevicePropertyNotification(); + for (Device.Property property : device.getProperties()) { + if ("SERIAL".equals(property.getName())) { + devicePropertyNotification.setSerial(property.getValue()); + } + if ("IMEI".equals((property.getName()))) { + devicePropertyNotification.setImei(property.getValue()); + } + } + DeviceEnrollmentInfoNotification deviceEnrollmentInfoNotification = new DeviceEnrollmentInfoNotification(); + deviceEnrollmentInfoNotification.setId(device.getEnrolmentInfo().getId()); + deviceEnrollmentInfoNotification.setOwner(device.getEnrolmentInfo().getOwner()); + deviceEnrollmentInfoNotification.setDateOfEnrolment(device.getEnrolmentInfo().getDateOfEnrolment()); + deviceEnrollmentInfoNotification.setDateOfLastUpdate(device.getEnrolmentInfo().getDateOfLastUpdate()); + deviceEnrollmentInfoNotification.setOwnership(device.getEnrolmentInfo().getOwnership().toString()); + deviceEnrollmentInfoNotification.setStatus(device.getEnrolmentInfo().getStatus().toString()); + + DeviceNotification deviceNotification = new DeviceNotification(device.getId(), device.getName(), + device.getType(), device.getDescription(), devicePropertyNotification, + deviceEnrollmentInfoNotification); + + JAXBContext jaxbContext = JAXBContext.newInstance(DeviceNotification.class); + Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); + jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + StringWriter sw = new StringWriter(); + jaxbMarshaller.marshal(deviceNotification, sw); + String payload = sw.toString(); + return new StringEntity(payload, ContentType.APPLICATION_XML); + } catch (JAXBException e) { + throw new EnrollmentNotifierException( + "Error occured when converting Device object into xml string. Hence enrollment notification payload " + + "constructing is failed", e); + } + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/resources/mssql-testng.xml b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/resources/mssql-testng.xml index 5c1f4cbe4ee..8f0a9de7138 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/resources/mssql-testng.xml +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/resources/mssql-testng.xml @@ -40,7 +40,7 @@ - + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/resources/mysql-testng.xml b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/resources/mysql-testng.xml index 7b02276ea6b..4240faeb80b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/resources/mysql-testng.xml +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/resources/mysql-testng.xml @@ -40,7 +40,7 @@ - + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/resources/oracle-testng.xml b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/resources/oracle-testng.xml index cb41dfc6202..9ec34795d40 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/resources/oracle-testng.xml +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/resources/oracle-testng.xml @@ -40,7 +40,7 @@ - + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/resources/postgre-testng.xml b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/resources/postgre-testng.xml index 6c516bc74de..fbaf2fd8a79 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/resources/postgre-testng.xml +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/resources/postgre-testng.xml @@ -40,7 +40,7 @@ - + diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/cdm-config.xml b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/cdm-config.xml index 62eb67b6d60..e1a6b7aef83 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/cdm-config.xml +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/cdm-config.xml @@ -148,5 +148,11 @@ 640 BYOD,COPE + + false + false + org.wso2.carbon.device.mgt.common.enrollment.notification.EnrollmentNotifier + http://localhost:8280 +