diff --git a/README.md b/README.md index 4cd3ea5a5..e45f297f7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ #carbon-device-mgt-plugins + + WSO2 MOBILE DEVICE MANAGER WSO2 Mobile Device Manager (WSO2 MDM) is a comprehensive platform that helps solve mobile computing challenges enterprises face today when dealing with both corporate owned, personally enabled (COPE) devices and employee owned devices as part of a bring your own device (BYOD) program. diff --git a/components/analytics/iot-analytics/org.wso2.carbon.device.mgt.iot.analytics/pom.xml b/components/analytics/iot-analytics/org.wso2.carbon.device.mgt.iot.analytics/pom.xml index 925456dbc..20c1fb35b 100644 --- a/components/analytics/iot-analytics/org.wso2.carbon.device.mgt.iot.analytics/pom.xml +++ b/components/analytics/iot-analytics/org.wso2.carbon.device.mgt.iot.analytics/pom.xml @@ -21,7 +21,7 @@ org.wso2.carbon.devicemgt-plugins iot-analytics - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/analytics/iot-analytics/org.wso2.carbon.iot.das.rest.api/pom.xml b/components/analytics/iot-analytics/org.wso2.carbon.iot.das.rest.api/pom.xml deleted file mode 100644 index 5deaf0ae2..000000000 --- a/components/analytics/iot-analytics/org.wso2.carbon.iot.das.rest.api/pom.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - org.wso2.carbon.devicemgt-plugins - iot-analytics - 3.0.3-SNAPSHOT - ../pom.xml - - - 4.0.0 - org.wso2.carbon.iot.das.rest.api - WSO2 Carbon - IoT Server REST API - pom - - - - - org.apache.felix - maven-scr-plugin - - - generate-scr-descriptor - - scr - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - org.apache.felix - maven-bundle-plugin - true - - - ${project.artifactId} - ${project.artifactId} - - - - - - - * - - - - - - - \ No newline at end of file diff --git a/components/analytics/iot-analytics/org.wso2.carbon.iot.device.statistics.dashboard/pom.xml b/components/analytics/iot-analytics/org.wso2.carbon.iot.device.statistics.dashboard/pom.xml index a2d9c0f6b..fcfcd9733 100644 --- a/components/analytics/iot-analytics/org.wso2.carbon.iot.device.statistics.dashboard/pom.xml +++ b/components/analytics/iot-analytics/org.wso2.carbon.iot.device.statistics.dashboard/pom.xml @@ -21,7 +21,7 @@ org.wso2.carbon.devicemgt-plugins iot-analytics - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/analytics/iot-analytics/org.wso2.carbon.iot.geo.dashboard/pom.xml b/components/analytics/iot-analytics/org.wso2.carbon.iot.geo.dashboard/pom.xml index 581c07c33..0354973b0 100644 --- a/components/analytics/iot-analytics/org.wso2.carbon.iot.geo.dashboard/pom.xml +++ b/components/analytics/iot-analytics/org.wso2.carbon.iot.geo.dashboard/pom.xml @@ -21,7 +21,7 @@ org.wso2.carbon.devicemgt-plugins iot-analytics - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/analytics/iot-analytics/pom.xml b/components/analytics/iot-analytics/pom.xml index 92ad61b0b..19d4f6f63 100644 --- a/components/analytics/iot-analytics/pom.xml +++ b/components/analytics/iot-analytics/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.devicemgt-plugins analytics - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/analytics/pom.xml b/components/analytics/pom.xml index 60cd864f2..90dcaf1e7 100644 --- a/components/analytics/pom.xml +++ b/components/analytics/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.devicemgt-plugins carbon-device-mgt-plugins-parent - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../../pom.xml diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseClientAsyncExecutor.java b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseClientAsyncExecutor.java index 6b1591ce9..fbfa0c014 100755 --- a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseClientAsyncExecutor.java +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseClientAsyncExecutor.java @@ -118,7 +118,8 @@ public class SenseClientAsyncExecutor extends AsyncTask androidsense-plugin org.wso2.carbon.devicemgt-plugins - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics/src/main/resources/carbonapps/androidsense/android_sense_receiver/android_sense_receiver.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics/src/main/resources/carbonapps/androidsense/android_sense_receiver/android_sense_receiver.xml index e94bf47ca..706610654 100644 --- a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics/src/main/resources/carbonapps/androidsense/android_sense_receiver/android_sense_receiver.xml +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics/src/main/resources/carbonapps/androidsense/android_sense_receiver/android_sense_receiver.xml @@ -19,10 +19,8 @@ - carbon.super/android_sense/+/data - admin - admin - org.wso2.carbon.device.mgt.input.adapter.mqtt.util.MQTTContentValidator + ${tenant-domain}/android_sense/+/data + iot-mqtt true diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/pom.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/pom.xml index fc1a18732..92e4ffb10 100644 --- a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/pom.xml +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/pom.xml @@ -3,7 +3,7 @@ androidsense-plugin org.wso2.carbon.devicemgt-plugins - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseService.java b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseService.java index aca23b632..8bf547f74 100644 --- a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseService.java +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseService.java @@ -56,7 +56,7 @@ import javax.ws.rs.core.Response; } ), tags = { - @Tag(name = "android_sense", description = "") + @Tag(name = "android_sense,device_management", description = "") } ) @Scopes( diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/APIUtil.java b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/APIUtil.java index aa8fda595..b057705f0 100644 --- a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/APIUtil.java +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/APIUtil.java @@ -21,9 +21,7 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfigurationManagementService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.constants.AndroidSenseConstants; -import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService; import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; -import org.wso2.carbon.utils.NetworkUtils; import java.net.SocketException; import java.util.ArrayList; @@ -176,18 +174,6 @@ public class APIUtil { return deviceAccessAuthorizationService; } - public static OutputEventAdapterService getOutputEventAdapterService() { - PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); - OutputEventAdapterService outputEventAdapterService = - (OutputEventAdapterService) ctx.getOSGiService(OutputEventAdapterService.class, null); - if (outputEventAdapterService == null) { - String msg = "Device Authorization service has not initialized."; - log.error(msg); - throw new IllegalStateException(msg); - } - return outputEventAdapterService; - } - public static String getTenantDomainOftheUser() { PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext(); return threadLocalCarbonContext.getTenantDomain(); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/pom.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/pom.xml index 03816ecd9..299532f53 100644 --- a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/pom.xml +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/pom.xml @@ -22,7 +22,7 @@ androidsense-plugin org.wso2.carbon.devicemgt-plugins - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.type-view/public/js/download.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.type-view/public/js/download.js index 082cc1586..fcb3c3754 100644 --- a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.type-view/public/js/download.js +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.type-view/public/js/download.js @@ -21,6 +21,8 @@ var modalPopupContainer = modalPopup + " .modal-content"; var modalPopupContent = modalPopup + " .modal-content"; var body = "body"; +var backendEndBasePath = "/api/device-mgt/v1.0"; + /* * set popup maximum height function. */ @@ -69,4 +71,32 @@ function attachEvents() { generateQRCode(modalPopupContent + " .qr-code"); modalDialog.show(); } -} \ No newline at end of file +} + +function artifactUpload() { + var contentType = "application/json"; + + var urix = backendEndBasePath + "/admin/devicetype/deploy/android_sense"; + var defaultStatusClasses = "fw fw-stack-1x"; + var content = $("#androidsense-statistic-response-template").find(".content"); + var title = content.find("#title"); + var statusIcon = content.find("#status-icon"); + var data = {} + invokerUtil.post(urix, data, function (data) { + title.html("Deploying statistic artifacts. Please wait..."); + statusIcon.attr("class", defaultStatusClasses + " fw-check"); + $(modalPopupContent).html(content.html()); + showPopup(); + setTimeout(function () { + hidePopup(); + location.reload(true); + }, 5000); + + }, function (jqXHR) { + title.html("Failed to deploy artifacts, Please contact administrator."); + statusIcon.attr("class", defaultStatusClasses + " fw-error"); + $(modalPopupContent).html(content.html()); + showPopup(); + }, contentType); +} + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.type-view/type-view.hbs b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.type-view/type-view.hbs index fdccd55d5..9c08451e9 100644 --- a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.type-view/type-view.hbs +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.type-view/type-view.hbs @@ -41,7 +41,9 @@ Enroll Device Download APK Invite by Email - + {{#if displayStatus}} + Deploy Analytics Artifacts + {{/if}} @@ -240,7 +242,26 @@ {{unit "cdmf.unit.device.type.email.invite-modal" deviceTypeView="androidSense"}} - + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.type-view/type-view.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.type-view/type-view.js index 8c8260405..adb857567 100644 --- a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.type-view/type-view.js +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.type-view/type-view.js @@ -19,6 +19,20 @@ function onRequest(context){ var viewModel = {}; var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"]; + var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"]; + var url = devicemgtProps["httpsURL"] + "/api/device-mgt/v1.0/admin/devicetype/deploy/android_sense/status"; + serviceInvokers.XMLHttp.get( + url, function (responsePayload) { + var responseContent = responsePayload.status; + new Log().error(responseContent); + if ("204" == responsePayload.status) { + viewModel["displayStatus"] = "Display"; + } + }, + function (responsePayload) { + //do nothing. + } + ); viewModel["hostName"] = devicemgtProps["generalConfig"]["host"]; viewModel["enrollmentURL"] = viewModel["hostName"] + context.unit.publicUri + "/asset/androidsense.apk"; return viewModel; diff --git a/components/device-types/androidsense-plugin/pom.xml b/components/device-types/androidsense-plugin/pom.xml index f25886b19..725be5dce 100644 --- a/components/device-types/androidsense-plugin/pom.xml +++ b/components/device-types/androidsense-plugin/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.devicemgt-plugins device-types - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/build.xml b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/build.xml index 1d35c7bf0..d6b5b26cc 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/build.xml +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/build.xml @@ -26,7 +26,7 @@ - + diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/pom.xml b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/pom.xml index 6b9ca04e0..e15a9ccaa 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/pom.xml +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/pom.xml @@ -21,7 +21,7 @@ arduino-plugin org.wso2.carbon.devicemgt-plugins - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/src/assembly/src.xml b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/src/assembly/src.xml index a5a375010..b7735b0b7 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/src/assembly/src.xml +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/src/assembly/src.xml @@ -17,8 +17,8 @@ --> src diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/src/main/resources/carbonapps/Arduino/arduino_execution/artifact.xml b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/src/main/resources/carbonapps/Arduino/arduino_execution/artifact.xml index a67055590..9438aceac 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/src/main/resources/carbonapps/Arduino/arduino_execution/artifact.xml +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/src/main/resources/carbonapps/Arduino/arduino_execution/artifact.xml @@ -18,6 +18,6 @@ --> - arduino_execution.siddhiql + arduino_execution.siddhiql diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/src/main/resources/carbonapps/Arduino/arduino_receiver/arduino_receiver.xml b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/src/main/resources/carbonapps/Arduino/arduino_receiver/arduino_receiver.xml index c8c306ef9..b20bafc96 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/src/main/resources/carbonapps/Arduino/arduino_receiver/arduino_receiver.xml +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/src/main/resources/carbonapps/Arduino/arduino_receiver/arduino_receiver.xml @@ -16,9 +16,10 @@ ~ specific language governing permissions and limitations ~ under the License. --> - + - org.wso2.carbon.device.mgt.input.adapter.http.util.HTTPContentValidator + iot-http diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/src/main/resources/carbonapps/Arduino/arduino_stream/artifact.xml b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/src/main/resources/carbonapps/Arduino/arduino_stream/artifact.xml index 8ba90edaf..8bf570bd6 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/src/main/resources/carbonapps/Arduino/arduino_stream/artifact.xml +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/src/main/resources/carbonapps/Arduino/arduino_stream/artifact.xml @@ -17,7 +17,7 @@ ~ under the License. --> - - org.wso2.iot.arduino_1.0.0.json + + org.wso2.iot.arduino_1.0.0.json diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/src/main/resources/carbonapps/Arduino/arduino_stream/org.wso2.iot.arduino_1.0.0.json b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/src/main/resources/carbonapps/Arduino/arduino_stream/org.wso2.iot.arduino_1.0.0.json index 71bd0e1bb..45566b7c9 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/src/main/resources/carbonapps/Arduino/arduino_stream/org.wso2.iot.arduino_1.0.0.json +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.analytics/src/main/resources/carbonapps/Arduino/arduino_stream/org.wso2.iot.arduino_1.0.0.json @@ -4,12 +4,19 @@ "nickName": "Arduino", "description": "Temperature data received from the Arduino", "metaData": [ - {"name":"owner","type":"STRING"}, - {"name":"deviceId","type":"STRING"} + { + "name": "owner", + "type": "STRING" + }, + { + "name": "deviceId", + "type": "STRING" + } ], "payloadData": [ { - "name": "temperature","type": "FLOAT" + "name": "temperature", + "type": "FLOAT" } ] } \ No newline at end of file diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/pom.xml b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/pom.xml index 532f22f17..047081302 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/pom.xml +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/pom.xml @@ -21,7 +21,7 @@ arduino-plugin org.wso2.carbon.devicemgt-plugins - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml @@ -144,7 +144,7 @@ org.wso2.carbon.devicemgt org.wso2.carbon.apimgt.annotations - provided + provided diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoService.java b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoService.java index 3ed382479..d04008cd6 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoService.java +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoService.java @@ -19,7 +19,6 @@ package org.wso2.carbon.device.mgt.iot.arduino.service.impl; import io.swagger.annotations.*; - import org.wso2.carbon.apimgt.annotations.api.Scope; import org.wso2.carbon.apimgt.annotations.api.Scopes; import org.wso2.carbon.device.mgt.iot.arduino.service.impl.constants.ArduinoConstants; @@ -40,7 +39,7 @@ import javax.ws.rs.core.Response; } ), tags = { - @Tag(name = "arduino", description = "") + @Tag(name = "arduino,device_management", description = "") } ) @Scopes( @@ -110,7 +109,7 @@ public interface ArduinoService { } ) Response getArduinoTemperatureStats(@PathParam("deviceId") String deviceId, @QueryParam("from") long from, - @QueryParam("to") long to); + @QueryParam("to") long to); /** * download device agent diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoServiceImpl.java b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoServiceImpl.java index b5c6b10d9..73c14c0bc 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoServiceImpl.java +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoServiceImpl.java @@ -148,7 +148,7 @@ public class ArduinoServiceImpl implements ArduinoService { @QueryParam("to") long to) { try { if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized(new DeviceIdentifier(deviceId, - ArduinoConstants.DEVICE_TYPE), DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) { + ArduinoConstants.DEVICE_TYPE), DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) { return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); } String fromDate = String.valueOf(from); @@ -179,13 +179,14 @@ public class ArduinoServiceImpl implements ArduinoService { @Produces("application/zip") public Response downloadSketch(@QueryParam("deviceName") String deviceName) { try { - ZipArchive zipFile = createDownloadFile(APIUtil.getAuthenticatedUser(), deviceName); - Response.ResponseBuilder response = Response.ok(FileUtils.readFileToByteArray(zipFile.getZipFile())); + String username = APIUtil.getAuthenticatedUser() + "@" + PrivilegedCarbonContext + .getThreadLocalCarbonContext().getTenantDomain(); + ZipArchive zipFile = createDownloadFile(username, deviceName); + Response.ResponseBuilder response = Response.ok(zipFile.getZipFileContent()); response.status(Response.Status.OK); response.type("application/zip"); response.header("Content-Disposition", "attachment; filename=\"" + zipFile.getFileName() + "\""); Response resp = response.build(); - zipFile.getZipFile().delete(); return resp; } catch (IllegalArgumentException ex) { return Response.status(400).entity(ex.getMessage()).build();//bad request @@ -198,9 +199,6 @@ public class ArduinoServiceImpl implements ArduinoService { } catch (APIManagerException ex) { log.error(ex.getMessage(), ex); return Response.status(500).entity(ex.getMessage()).build(); - } catch (IOException ex) { - log.error(ex.getMessage(), ex); - return Response.status(500).entity(ex.getMessage()).build(); } catch (UserStoreException ex) { log.error(ex.getMessage(), ex); return Response.status(500).entity(ex.getMessage()).build(); @@ -209,7 +207,7 @@ public class ArduinoServiceImpl implements ArduinoService { private ZipArchive createDownloadFile(String owner, String deviceName) throws DeviceManagementException, JWTClientException, APIManagerException, - UserStoreException { + UserStoreException { if (owner == null) { throw new IllegalArgumentException("Error on createDownloadFile() Owner is null!"); } @@ -221,7 +219,9 @@ public class ArduinoServiceImpl implements ArduinoService { throw new DeviceManagementException(msg); } String applicationUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() - .getRealmConfiguration().getAdminUserName(); + .getRealmConfiguration().getAdminUserName() + "@" + PrivilegedCarbonContext + .getThreadLocalCarbonContext().getTenantDomain(); + ; if (apiApplicationKey == null) { APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService(); String[] tags = {ArduinoConstants.DEVICE_TYPE}; @@ -232,14 +232,14 @@ public class ArduinoServiceImpl implements ArduinoService { JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient(); String scopes = " device_" + deviceId + " perm:arduino:enroll"; AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(), - apiApplicationKey.getConsumerSecret(), owner, scopes); + apiApplicationKey.getConsumerSecret(), owner, scopes); //create token String accessToken = accessTokenInfo.getAccessToken(); String refreshToken = accessTokenInfo.getRefreshToken(); //Register the device with CDMF ZipUtil ziputil = new ZipUtil(); return ziputil.createZipFile(owner, APIUtil.getTenantDomainOftheUser(), - ArduinoConstants.DEVICE_TYPE, deviceId, deviceName, accessToken, refreshToken); + ArduinoConstants.DEVICE_TYPE, deviceId, deviceName, accessToken, refreshToken); } private static String shortUUID() { diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/util/ZipArchive.java b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/util/ZipArchive.java index 1048e8769..7633dddbc 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/util/ZipArchive.java +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/util/ZipArchive.java @@ -25,16 +25,16 @@ import java.io.File; */ public class ZipArchive { - private File zipFile = null; + private byte[] zipFileContent = null; private String fileName = null; - public ZipArchive(String fileName, File zipFile) { + public ZipArchive(String fileName, byte[] zipFile) { this.fileName = fileName; - this.zipFile = zipFile; + this.zipFileContent = zipFile; } - public File getZipFile() { - return zipFile; + public byte[] getZipFileContent() { + return zipFileContent; } public String getFileName() { diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/util/ZipUtil.java b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/util/ZipUtil.java index 627ced256..66b99da1e 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/util/ZipUtil.java +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/util/ZipUtil.java @@ -34,6 +34,7 @@ import org.wso2.carbon.utils.NetworkUtils; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -57,7 +58,6 @@ import java.util.zip.ZipOutputStream; */ public class ZipUtil { - private static final String HTTP_PORT_PROPERTY = "httpPort"; private static final String CONFIG_TYPE = "general"; private static final Log log = LogFactory.getLog(ZipUtil.class); private static final String LOCALHOST = "localhost"; @@ -69,8 +69,6 @@ public class ZipUtil { String refreshToken) throws DeviceManagementException { String sketchFolder = "repository" + File.separator + "resources" + File.separator + "sketches"; - String archivesPath = CarbonUtils.getCarbonHome() + File.separator + sketchFolder + File.separator + "archives" + - File.separator + deviceId; String templateSketchPath = sketchFolder + File.separator + deviceType; String iotServerIP; @@ -113,7 +111,7 @@ public class ZipUtil { contextParams.put("DEVICE_REFRESH_TOKEN", refreshToken); ZipArchive zipFile; - zipFile = getSketchArchive(archivesPath, templateSketchPath, contextParams, deviceName); + zipFile = getSketchArchive(templateSketchPath, contextParams, deviceName); return zipFile; } catch (IOException e) { throw new DeviceManagementException("Zip File Creation Failed", e); @@ -122,7 +120,7 @@ public class ZipUtil { } } - public static String getServerUrl() { + private static String getServerUrl() { try { return org.apache.axis2.util.Utils.getIpAddress(); } catch (SocketException e) { @@ -131,32 +129,26 @@ public class ZipUtil { } } - private static ZipArchive getSketchArchive(String archivesPath, String templateSketchPath, Map contextParams + private ZipArchive getSketchArchive(String templateSketchPath, Map contextParams , String zipFileName) throws DeviceManagementException, IOException { String sketchPath = CarbonUtils.getCarbonHome() + File.separator + templateSketchPath; - FileUtils.deleteDirectory(new File(archivesPath));//clear directory - FileUtils.deleteDirectory(new File(archivesPath + ".zip"));//clear zip - if (!new File(archivesPath).mkdirs()) { //new dir - String message = "Could not create directory at path: " + archivesPath; - log.error(message); - throw new DeviceManagementException(message); - } zipFileName = zipFileName + ".zip"; try { Map> properties = getProperties(sketchPath + File.separator + "sketch" + ".properties"); List templateFiles = properties.get("templates"); + List processTemplateFiles = new ArrayList<>(); for (String templateFile : templateFiles) { - parseTemplate(templateSketchPath + File.separator + templateFile, archivesPath + File.separator + templateFile, - contextParams); + TemplateFile tFile = new TemplateFile(); + tFile.setContent(parseTemplate(templateSketchPath + File.separator + templateFile, contextParams)); + tFile.setFileName(templateFile); + processTemplateFiles.add(tFile); } templateFiles.add("sketch.properties"); // ommit copying the props file - copyFolder(new File(sketchPath), new File(archivesPath), templateFiles); - createZipArchive(archivesPath); - FileUtils.deleteDirectory(new File(archivesPath)); - File zip = new File(archivesPath + ".zip"); + + byte[] zip = createZipArchive(templateSketchPath, processTemplateFiles); return new ZipArchive(zipFileName, zip); } catch (IOException ex) { throw new DeviceManagementException( @@ -196,148 +188,124 @@ public class ZipUtil { } } - private static void parseTemplate(String srcFile, String dstFile, Map contextParams) throws IOException { + private static String parseTemplate(String srcFile, Map contextParams) throws IOException { //read from file FileInputStream inputStream = null; - FileOutputStream outputStream = null; try { inputStream = new FileInputStream(srcFile); - outputStream = new FileOutputStream(dstFile); String content = IOUtils.toString(inputStream, StandardCharsets.UTF_8.toString()); Iterator iterator = contextParams.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry mapEntry = (Map.Entry) iterator.next(); content = content.replaceAll("\\$\\{" + mapEntry.getKey() + "\\}", mapEntry.getValue().toString()); } - IOUtils.write(content, outputStream, StandardCharsets.UTF_8.toString()); + return content; } finally { if (inputStream != null) { inputStream.close(); } - if (outputStream != null) { - outputStream.close(); - } - } - } - - private static void copyFolder(File src, File dest, List excludeFileNames) throws IOException { - - if (src.isDirectory()) { - //if directory not exists, create it - if (!dest.exists() && !dest.mkdirs()) { - String message = "Could not create directory at path: " + dest; - log.error(message); - throw new IOException(message); - } - //list all the directory contents - String files[] = src.list(); - - if (files == null) { - log.warn("There are no files insides the directory " + src.getAbsolutePath()); - return; - } - - for (String file : files) { - //construct the src and dest file structure - File srcFile = new File(src, file); - File destFile = new File(dest, file); - //recursive copy - copyFolder(srcFile, destFile, excludeFileNames); - } - - } else { - for (String fileName : excludeFileNames) { - if (src.getName().equals(fileName)) { - return; - } - } - //if file, then copy it - //Use bytes stream to support all file types - InputStream in = null; - OutputStream out = null; - - try { - in = new FileInputStream(src); - out = new FileOutputStream(dest); - - byte[] buffer = new byte[1024]; - - int length; - //copy the file content in bytes - while ((length = in.read(buffer)) > 0) { - out.write(buffer, 0, length); - } - } finally { - if (in != null) { - in.close(); - } - if (out != null) { - out.close(); - } - } } } - private static boolean createZipArchive(String srcFolder) throws IOException { - BufferedInputStream origin = null; + private static byte[] createZipArchive(String srcFolder, List processTemplateFiles) throws IOException { ZipOutputStream out = null; - + ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { - final int BUFFER = 2048; - FileOutputStream dest = new FileOutputStream(new File(srcFolder + ".zip")); - out = new ZipOutputStream(new BufferedOutputStream(dest)); - byte data[] = new byte[BUFFER]; + out = new ZipOutputStream(new BufferedOutputStream(baos)); File subDir = new File(srcFolder); String subdirList[] = subDir.list(); if (subdirList == null) { log.warn("The sub directory " + subDir.getAbsolutePath() + " is empty"); - return false; + return null; } for (String sd : subdirList) { // get a list of files from current directory - File f = new File(srcFolder + "/" + sd); + File f = new File(srcFolder + File.separator + sd); if (f.isDirectory()) { String files[] = f.list(); if (files == null) { log.warn("The current directory " + f.getAbsolutePath() + " is empty. Has no files"); - return false; + return null; } for (int i = 0; i < files.length; i++) { - FileInputStream fi = new FileInputStream(srcFolder + "/" + sd + "/" + files[i]); - origin = new BufferedInputStream(fi, BUFFER); - ZipEntry entry = new ZipEntry(sd + "/" + files[i]); - out.putNextEntry(entry); - int count; - while ((count = origin.read(data, 0, BUFFER)) != -1) { - out.write(data, 0, count); - out.flush(); + boolean fileAdded = false; + for (TemplateFile templateFile : processTemplateFiles) { + if (files[i].equals(templateFile.getFileName())) { + ZipEntry entry = new ZipEntry(templateFile.getFileName()); + out.putNextEntry(entry); + out.write(templateFile.getContent().getBytes()); + out.closeEntry(); + fileAdded = true; + break; + } else if (f.getName().equals("sketch.properties")) { + fileAdded = true; + break; + } + } + if (fileAdded) { + continue; } + ZipEntry entry = new ZipEntry(sd + File.separator + files[i]); + out.putNextEntry(entry); + out.write(IOUtils.toByteArray(new FileInputStream(srcFolder + File.separator + sd + + File.separator + files[i]))); + out.closeEntry(); } } else //it is just a file { - FileInputStream fi = new FileInputStream(f); - origin = new BufferedInputStream(fi, BUFFER); + boolean fileAdded = false; + for (TemplateFile templateFile : processTemplateFiles) { + if (f.getName().equals(templateFile.getFileName())) { + ZipEntry entry = new ZipEntry(templateFile.getFileName()); + out.putNextEntry(entry); + out.write(templateFile.getContent().getBytes()); + out.closeEntry(); + fileAdded = true; + break; + } else if (f.getName().equals("sketch.properties")) { + fileAdded = true; + break; + } + } + if (fileAdded) { + continue; + } ZipEntry entry = new ZipEntry(sd); out.putNextEntry(entry); - int count; - while ((count = origin.read(data, 0, BUFFER)) != -1) { - out.write(data, 0, count); - out.flush(); - } + out.write(IOUtils.toByteArray(new FileInputStream(f))); + out.closeEntry(); } } - out.flush(); + out.finish(); } finally { - if (origin != null) { - origin.close(); - } if (out != null) { out.close(); } } - return true; + return baos.toByteArray(); + } + + public class TemplateFile { + private String content; + private String fileName; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } } } diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/webapp/META-INF/permissions.xml b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/webapp/META-INF/permissions.xml index eb8e9f67f..1a3a06be4 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/webapp/META-INF/permissions.xml +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/webapp/META-INF/permissions.xml @@ -26,16 +26,16 @@ it will result 403 error at the runtime. --> - - + + - - control bulb - /device-mgt/user/operations - /device/*/bulb - POST - arduino_user - + + control bulb + /device-mgt/user/operations + /device/*/bulb + POST + arduino_user + get controls /device-mgt/user/operations diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/webapp/WEB-INF/cxf-servlet.xml index a5b895b00..698d88d81 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/webapp/WEB-INF/cxf-servlet.xml +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -16,9 +16,9 @@ ~ limitations under the License. --> - @@ -30,7 +30,7 @@ - + diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/webapp/WEB-INF/web.xml b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/webapp/WEB-INF/web.xml index 660a6968b..dd95fb2d4 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/webapp/WEB-INF/web.xml +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/webapp/WEB-INF/web.xml @@ -1,11 +1,11 @@ - - Arduino - Arduino + Arduino + Arduino CXFServlet @@ -20,10 +20,6 @@ doAuthentication true - - isSharedWithAllTenants - true - @@ -32,7 +28,8 @@ - org.wso2.carbon.device.mgt.iot.arduino.service.impl.listener.ArduinoPermissionUpdateListener + org.wso2.carbon.device.mgt.iot.arduino.service.impl.listener.ArduinoPermissionUpdateListener + \ No newline at end of file diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/pom.xml b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/pom.xml index 385570c29..6012938ad 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/pom.xml +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/pom.xml @@ -23,7 +23,7 @@ arduino-plugin org.wso2.carbon.devicemgt-plugins - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/assembly/src.xml b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/assembly/src.xml index 2797034e0..c83a445e0 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/assembly/src.xml +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/assembly/src.xml @@ -17,8 +17,8 @@ --> src diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.analytics-view/analytics-view.js b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.analytics-view/analytics-view.js index 448d2eeff..689eeb7fa 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.analytics-view/analytics-view.js +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.analytics-view/analytics-view.js @@ -18,7 +18,7 @@ function onRequest(context) { var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"]; - + var devices = context.unit.params.devices; var deviceType = context.uriParams.deviceType; var deviceId = request.getParameter("deviceId"); @@ -26,7 +26,7 @@ function onRequest(context) { if (devices) { return { "devices": stringify(devices), - "backendApiUri": "/arduino/device/stats/" + "backendApiUri": "/arduino/device/stats/" }; } else if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) { var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"]; diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.analytics-view/public/js/arduino.js b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.analytics-view/public/js/arduino.js index 76d5cb040..d4bf85b54 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.analytics-view/public/js/arduino.js +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.analytics-view/public/js/arduino.js @@ -48,25 +48,25 @@ function drawGraph_arduino(from, to) { if (devices) { for (var i = 0; i < devices.length; i++) { graphConfig['series'].push( - { - 'color': palette.color(), - 'data': [{ - x: parseInt(new Date().getTime() / 1000), - y: 0 - }], - 'name': devices[i].name - }); - } - } else { - graphConfig['series'].push( { 'color': palette.color(), 'data': [{ x: parseInt(new Date().getTime() / 1000), y: 0 }], - 'name': $("#arduino-details").data("devicename") + 'name': devices[i].name }); + } + } else { + graphConfig['series'].push( + { + 'color': palette.color(), + 'data': [{ + x: parseInt(new Date().getTime() / 1000), + y: 0 + }], + 'name': $("#arduino-details").data("devicename") + }); } var graph = new Rickshaw.Graph(graphConfig); @@ -103,9 +103,9 @@ function drawGraph_arduino(from, to) { graph: graph, formatter: function (series, x, y) { var date = '' + - moment((x + tzOffset) * 1000).format('Do MMM YYYY h:mm:ss a') + ''; + moment((x + tzOffset) * 1000).format('Do MMM YYYY h:mm:ss a') + ''; var swatch = ''; + series.color + '">'; return swatch + series.name + ": " + parseInt(y) + '
' + date; } }); @@ -145,7 +145,7 @@ function drawGraph_arduino(from, to) { return; } var backendApiUrl = $("#arduino-div-chart").data("backend-api-url") + devices[deviceIndex].deviceIdentifier - + "?from=" + from + "&to=" + to; + + "?from=" + from + "&to=" + to; var successCallback = function (data) { if (data) { drawLineGraph(JSON.parse(data)); @@ -167,10 +167,10 @@ function drawGraph_arduino(from, to) { var chartData = []; for (var i = 0; i < data.length; i++) { chartData.push( - { - x: parseInt(data[i].values.time) - tzOffset, - y: parseInt(data[i].values.temperature) - } + { + x: parseInt(data[i].values.time) - tzOffset, + y: parseInt(data[i].values.temperature) + } ); } diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.device-view/device-view.hbs b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.device-view/device-view.hbs index 4f9f3a6e3..a85c908e6 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.device-view/device-view.hbs +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.device-view/device-view.hbs @@ -33,14 +33,14 @@
{{unit "cdmf.unit.device.operation-bar" device=device autoCompleteParams=autoCompleteParams - encodedFeaturePayloads=encodedFeaturePayloads}} + encodedFeaturePayloads=encodedFeaturePayloads}}
{{/zone}} {{#zone "device-view-tabs"}}
  • Device - Statistics + Statistics
  • Operations Log
  • diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.device-view/device-view.js b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.device-view/device-view.js index 9ea752caa..76a614154 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.device-view/device-view.js +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.device-view/device-view.js @@ -22,20 +22,20 @@ function onRequest(context) { var deviceId = request.getParameter("id"); var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"]; var autoCompleteParams = [ - {"name" : "deviceId", "value" : deviceId} + {"name": "deviceId", "value": deviceId} ]; if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) { var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"]; var device = deviceModule.viewDevice(deviceType, deviceId); if (device && device.status != "error") { - var anchor = { "device" : { "id" : device.content.deviceIdentifier, "type" : device.content.type}}; + var anchor = {"device": {"id": device.content.deviceIdentifier, "type": device.content.type}}; return { "device": device.content, - "autoCompleteParams" : autoCompleteParams, + "autoCompleteParams": autoCompleteParams, "encodedFeaturePayloads": "", - "portalUrl" : devicemgtProps['portalURL'], - "anchor" : JSON.stringify(anchor) + "portalUrl": devicemgtProps['portalURL'], + "anchor": JSON.stringify(anchor) }; } else { response.sendError(404, "Device Id " + deviceId + " of type " + deviceType + " cannot be found!"); diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.device-view/device-view.json b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.device-view/device-view.json index 9eecd8f5b..688e93980 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.device-view/device-view.json +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.device-view/device-view.json @@ -1,3 +1,3 @@ { - "version": "1.0.0" + "version": "1.0.0" } \ No newline at end of file diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.platform.configuration/configuration.hbs b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.platform.configuration/configuration.hbs index 212288497..49dcbcd12 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.platform.configuration/configuration.hbs +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.platform.configuration/configuration.hbs @@ -30,7 +30,7 @@
    diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.platform.configuration/configuration.json b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.platform.configuration/configuration.json index fd2590129..688e93980 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.platform.configuration/configuration.json +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.platform.configuration/configuration.json @@ -1,3 +1,3 @@ { - "version" : "1.0.0" + "version": "1.0.0" } \ No newline at end of file diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.realtime.analytics-view/analytics-view.js b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.realtime.analytics-view/analytics-view.js index 7aaad19c6..25017af81 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.realtime.analytics-view/analytics-view.js +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.realtime.analytics-view/analytics-view.js @@ -31,7 +31,7 @@ function onRequest(context) { if (encodedClientKeys) { var tokenUtil = require("/app/modules/oauth/token-handler-utils.js")["utils"]; var resp = tokenUtil.decode(encodedClientKeys).split(":"); - var tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username,"default", {}); + var tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username, "default", {}); if (tokenPair) { token = tokenPair.accessToken; } diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.realtime.analytics-view/public/js/device-stats.js b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.realtime.analytics-view/public/js/device-stats.js index a67ff50db..c7a08f93b 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.realtime.analytics-view/public/js/device-stats.js +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.realtime.analytics-view/public/js/device-stats.js @@ -25,9 +25,9 @@ $(window).load(function () { var tNow = new Date().getTime() / 1000; for (var i = 0; i < 30; i++) { chartData.push({ - x: tNow - (30 - i) * 15, - y: parseFloat(0) - }); + x: tNow - (30 - i) * 15, + y: parseFloat(0) + }); } graph = new Rickshaw.Graph({ @@ -90,9 +90,9 @@ function connect(target) { ws.onmessage = function (event) { var dataPoint = JSON.parse(event.data); chartData.push({ - x: parseInt(dataPoint[0]) / 1000, - y: parseFloat(dataPoint[5]) - }); + x: parseInt(dataPoint[0]) / 1000, + y: parseFloat(dataPoint[5]) + }); chartData.shift(); graph.update(); }; diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/private/config.json b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/private/config.json index 74d66878d..b2bc55814 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/private/config.json +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/private/config.json @@ -4,7 +4,7 @@ "category": "iot", "downloadAgentUri": "arduino/device/download", "category": "iot", - "scopes" : [ + "scopes": [ "perm:arduino:enroll" ] } diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/public/css/styles.css b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/public/css/styles.css index a64a07abc..44a3a24b1 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/public/css/styles.css +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/public/css/styles.css @@ -21,15 +21,19 @@ width: 50px; color: #fff; } + .padding-top-double { padding-top: 20px; } + .padding-double { padding: 20px; } + .grey { color: #333; } + hr { display: block; height: 1px; @@ -39,20 +43,25 @@ hr { padding: 0; opacity: 0.2; } + .light-grey { color: #7c7c7c; } + .uppercase { text-transform: uppercase; } + .grey-bg { background-color: #f6f4f4; } -.doc-link{ + +.doc-link { background: none; color: #000; padding: 10px 0px; } + .doc-link a { color: #006eff; } diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/public/js/download.js b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/public/js/download.js index 3b104cd53..311d058d9 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/public/js/download.js +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/public/js/download.js @@ -21,6 +21,8 @@ var modalPopupContainer = modalPopup + " .modal-content"; var modalPopupContent = modalPopup + " .modal-content"; var body = "body"; +var backendEndBasePath = "/api/device-mgt/v1.0"; + /* * set popup maximum height function. */ @@ -108,15 +110,15 @@ function attachEvents() { doAction(data); } ); - }else if(deviceName){ + } else if (deviceName) { $('.controls').append(''); + 'style="display: inline-block;">Please enter at least 4 ' + + 'characters.'); $('.control-group').removeClass('success').addClass('error'); } else { $('.controls').append(''); + 'style="display: inline-block;">This field is required.' + + ''); $('.control-group').removeClass('success').addClass('error'); } }); @@ -144,7 +146,7 @@ function downloadAgent() { setTimeout(function () { hidePopup(); }, 1000); - }else { + } else { $("#invalid-username-error-msg span").text("Invalid device name"); $("#invalid-username-error-msg").removeClass("hidden"); } @@ -181,4 +183,31 @@ function doAction(data) { hidePopup(); }); } +} + +function artifactUpload() { + var contentType = "application/json"; + + var urix = backendEndBasePath + "/admin/devicetype/deploy/arduino"; + var defaultStatusClasses = "fw fw-stack-1x"; + var content = $("#arduino-statistic-response-template").find(".content"); + var title = content.find("#title"); + var statusIcon = content.find("#status-icon"); + var data = {} + invokerUtil.post(urix, data, function (data) { + title.html("Deploying statistic artifacts. Please wait..."); + statusIcon.attr("class", defaultStatusClasses + " fw-check"); + $(modalPopupContent).html(content.html()); + showPopup(); + setTimeout(function () { + hidePopup(); + location.reload(true); + }, 5000); + + }, function (jqXHR) { + title.html("Failed to deploy artifacts, Please contact administrator."); + statusIcon.attr("class", defaultStatusClasses + " fw-error"); + $(modalPopupContent).html(content.html()); + showPopup(); + }, contentType); } \ No newline at end of file diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/public/js/jquery.validate.js b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/public/js/jquery.validate.js index fe7ecf07a..75903e12c 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/public/js/jquery.validate.js +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/public/js/jquery.validate.js @@ -16,1212 +16,1219 @@ * under the License. */ -(function($) { - -$.extend($.fn, { - // http://docs.jquery.com/Plugins/Validation/validate - validate: function( options ) { - - // if nothing is selected, return nothing; can't chain anyway - if ( !this.length ) { - if ( options && options.debug && window.console ) { - console.warn( "Nothing selected, can't validate, returning nothing." ); - } - return; - } - - // check if a validator for this form was already created - var validator = $.data( this[0], "validator" ); - if ( validator ) { - return validator; - } - - // Add novalidate tag if HTML5. - this.attr( "novalidate", "novalidate" ); - - validator = new $.validator( options, this[0] ); - $.data( this[0], "validator", validator ); - - if ( validator.settings.onsubmit ) { - - this.validateDelegate( ":submit", "click", function( event ) { - if ( validator.settings.submitHandler ) { - validator.submitButton = event.target; - } - // allow suppressing validation by adding a cancel class to the submit button - if ( $(event.target).hasClass("cancel") ) { - validator.cancelSubmit = true; - } - }); - - // validate the form on submit - this.submit( function( event ) { - if ( validator.settings.debug ) { - // prevent form submit to be able to see console output - event.preventDefault(); - } - function handle() { - var hidden; - if ( validator.settings.submitHandler ) { - if ( validator.submitButton ) { - // insert a hidden input as a replacement for the missing submit button - hidden = $("").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm); - } - validator.settings.submitHandler.call( validator, validator.currentForm, event ); - if ( validator.submitButton ) { - // and clean up afterwards; thanks to no-block-scope, hidden can be referenced - hidden.remove(); - } - return false; - } - return true; - } - - // prevent submit for invalid forms or custom submit handlers - if ( validator.cancelSubmit ) { - validator.cancelSubmit = false; - return handle(); - } - if ( validator.form() ) { - if ( validator.pendingRequest ) { - validator.formSubmitted = true; - return false; - } - return handle(); - } else { - validator.focusInvalid(); - return false; - } - }); - } - - return validator; - }, - // http://docs.jquery.com/Plugins/Validation/valid - valid: function() { - if ( $(this[0]).is("form")) { - return this.validate().form(); - } else { - var valid = true; - var validator = $(this[0].form).validate(); - this.each(function() { - valid &= validator.element(this); - }); - return valid; - } - }, - // attributes: space seperated list of attributes to retrieve and remove - removeAttrs: function( attributes ) { - var result = {}, - $element = this; - $.each(attributes.split(/\s/), function( index, value ) { - result[value] = $element.attr(value); - $element.removeAttr(value); - }); - return result; - }, - // http://docs.jquery.com/Plugins/Validation/rules - rules: function( command, argument ) { - var element = this[0]; - - if ( command ) { - var settings = $.data(element.form, "validator").settings; - var staticRules = settings.rules; - var existingRules = $.validator.staticRules(element); - switch(command) { - case "add": - $.extend(existingRules, $.validator.normalizeRule(argument)); - staticRules[element.name] = existingRules; - if ( argument.messages ) { - settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages ); - } - break; - case "remove": - if ( !argument ) { - delete staticRules[element.name]; - return existingRules; - } - var filtered = {}; - $.each(argument.split(/\s/), function( index, method ) { - filtered[method] = existingRules[method]; - delete existingRules[method]; - }); - return filtered; - } - } - - var data = $.validator.normalizeRules( - $.extend( - {}, - $.validator.classRules(element), - $.validator.attributeRules(element), - $.validator.dataRules(element), - $.validator.staticRules(element) - ), element); - - // make sure required is at front - if ( data.required ) { - var param = data.required; - delete data.required; - data = $.extend({required: param}, data); - } - - return data; - } -}); +(function ($) { + + $.extend($.fn, { + // http://docs.jquery.com/Plugins/Validation/validate + validate: function (options) { + + // if nothing is selected, return nothing; can't chain anyway + if (!this.length) { + if (options && options.debug && window.console) { + console.warn("Nothing selected, can't validate, returning nothing."); + } + return; + } + + // check if a validator for this form was already created + var validator = $.data(this[0], "validator"); + if (validator) { + return validator; + } + + // Add novalidate tag if HTML5. + this.attr("novalidate", "novalidate"); + + validator = new $.validator(options, this[0]); + $.data(this[0], "validator", validator); + + if (validator.settings.onsubmit) { + + this.validateDelegate(":submit", "click", function (event) { + if (validator.settings.submitHandler) { + validator.submitButton = event.target; + } + // allow suppressing validation by adding a cancel class to the submit button + if ($(event.target).hasClass("cancel")) { + validator.cancelSubmit = true; + } + }); + + // validate the form on submit + this.submit(function (event) { + if (validator.settings.debug) { + // prevent form submit to be able to see console output + event.preventDefault(); + } + function handle() { + var hidden; + if (validator.settings.submitHandler) { + if (validator.submitButton) { + // insert a hidden input as a replacement for the missing submit button + hidden = $("").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm); + } + validator.settings.submitHandler.call(validator, validator.currentForm, event); + if (validator.submitButton) { + // and clean up afterwards; thanks to no-block-scope, hidden can be referenced + hidden.remove(); + } + return false; + } + return true; + } + + // prevent submit for invalid forms or custom submit handlers + if (validator.cancelSubmit) { + validator.cancelSubmit = false; + return handle(); + } + if (validator.form()) { + if (validator.pendingRequest) { + validator.formSubmitted = true; + return false; + } + return handle(); + } else { + validator.focusInvalid(); + return false; + } + }); + } + + return validator; + }, + // http://docs.jquery.com/Plugins/Validation/valid + valid: function () { + if ($(this[0]).is("form")) { + return this.validate().form(); + } else { + var valid = true; + var validator = $(this[0].form).validate(); + this.each(function () { + valid &= validator.element(this); + }); + return valid; + } + }, + // attributes: space seperated list of attributes to retrieve and remove + removeAttrs: function (attributes) { + var result = {}, + $element = this; + $.each(attributes.split(/\s/), function (index, value) { + result[value] = $element.attr(value); + $element.removeAttr(value); + }); + return result; + }, + // http://docs.jquery.com/Plugins/Validation/rules + rules: function (command, argument) { + var element = this[0]; + + if (command) { + var settings = $.data(element.form, "validator").settings; + var staticRules = settings.rules; + var existingRules = $.validator.staticRules(element); + switch (command) { + case "add": + $.extend(existingRules, $.validator.normalizeRule(argument)); + staticRules[element.name] = existingRules; + if (argument.messages) { + settings.messages[element.name] = $.extend(settings.messages[element.name], argument.messages); + } + break; + case "remove": + if (!argument) { + delete staticRules[element.name]; + return existingRules; + } + var filtered = {}; + $.each(argument.split(/\s/), function (index, method) { + filtered[method] = existingRules[method]; + delete existingRules[method]; + }); + return filtered; + } + } + + var data = $.validator.normalizeRules( + $.extend( + {}, + $.validator.classRules(element), + $.validator.attributeRules(element), + $.validator.dataRules(element), + $.validator.staticRules(element) + ), element); + + // make sure required is at front + if (data.required) { + var param = data.required; + delete data.required; + data = $.extend({required: param}, data); + } + + return data; + } + }); // Custom selectors -$.extend($.expr[":"], { - // http://docs.jquery.com/Plugins/Validation/blank - blank: function( a ) { return !$.trim("" + a.value); }, - // http://docs.jquery.com/Plugins/Validation/filled - filled: function( a ) { return !!$.trim("" + a.value); }, - // http://docs.jquery.com/Plugins/Validation/unchecked - unchecked: function( a ) { return !a.checked; } -}); + $.extend($.expr[":"], { + // http://docs.jquery.com/Plugins/Validation/blank + blank: function (a) { + return !$.trim("" + a.value); + }, + // http://docs.jquery.com/Plugins/Validation/filled + filled: function (a) { + return !!$.trim("" + a.value); + }, + // http://docs.jquery.com/Plugins/Validation/unchecked + unchecked: function (a) { + return !a.checked; + } + }); // constructor for validator -$.validator = function( options, form ) { - this.settings = $.extend( true, {}, $.validator.defaults, options ); - this.currentForm = form; - this.init(); -}; - -$.validator.format = function( source, params ) { - if ( arguments.length === 1 ) { - return function() { - var args = $.makeArray(arguments); - args.unshift(source); - return $.validator.format.apply( this, args ); - }; - } - if ( arguments.length > 2 && params.constructor !== Array ) { - params = $.makeArray(arguments).slice(1); - } - if ( params.constructor !== Array ) { - params = [ params ]; - } - $.each(params, function( i, n ) { - source = source.replace( new RegExp("\\{" + i + "\\}", "g"), function() { - return n; - }); - }); - return source; -}; - -$.extend($.validator, { - - defaults: { - messages: {}, - groups: {}, - rules: {}, - errorClass: "error", - validClass: "valid", - errorElement: "label", - focusInvalid: true, - errorContainer: $([]), - errorLabelContainer: $([]), - onsubmit: true, - ignore: ":hidden", - ignoreTitle: false, - onfocusin: function( element, event ) { - this.lastActive = element; - - // hide error label and remove error class on focus if enabled - if ( this.settings.focusCleanup && !this.blockFocusCleanup ) { - if ( this.settings.unhighlight ) { - this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass ); - } - this.addWrapper(this.errorsFor(element)).hide(); - } - }, - onfocusout: function( element, event ) { - if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) { - this.element(element); - } - }, - onkeyup: function( element, event ) { - if ( event.which === 9 && this.elementValue(element) === "" ) { - return; - } else if ( element.name in this.submitted || element === this.lastElement ) { - this.element(element); - } - }, - onclick: function( element, event ) { - // click on selects, radiobuttons and checkboxes - if ( element.name in this.submitted ) { - this.element(element); - } - // or option elements, check parent select in that case - else if ( element.parentNode.name in this.submitted ) { - this.element(element.parentNode); - } - }, - highlight: function( element, errorClass, validClass ) { - if ( element.type === "radio" ) { - this.findByName(element.name).addClass(errorClass).removeClass(validClass); - } else { - $(element).addClass(errorClass).removeClass(validClass); - } - }, - unhighlight: function( element, errorClass, validClass ) { - if ( element.type === "radio" ) { - this.findByName(element.name).removeClass(errorClass).addClass(validClass); - } else { - $(element).removeClass(errorClass).addClass(validClass); - } - } - }, - - // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults - setDefaults: function( settings ) { - $.extend( $.validator.defaults, settings ); - }, - - messages: { - required: "This field is required.", - remote: "Please fix this field.", - email: "Please enter a valid email address.", - url: "Please enter a valid URL.", - date: "Please enter a valid date.", - dateISO: "Please enter a valid date (ISO).", - number: "Please enter a valid number.", - digits: "Please enter only digits.", - creditcard: "Please enter a valid credit card number.", - equalTo: "Please enter the same value again.", - maxlength: $.validator.format("Please enter no more than {0} characters."), - minlength: $.validator.format("Please enter at least {0} characters."), - rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."), - range: $.validator.format("Please enter a value between {0} and {1}."), - max: $.validator.format("Please enter a value less than or equal to {0}."), - min: $.validator.format("Please enter a value greater than or equal to {0}.") - }, - - autoCreateRanges: false, - - prototype: { - - init: function() { - this.labelContainer = $(this.settings.errorLabelContainer); - this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm); - this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer ); - this.submitted = {}; - this.valueCache = {}; - this.pendingRequest = 0; - this.pending = {}; - this.invalid = {}; - this.reset(); - - var groups = (this.groups = {}); - $.each(this.settings.groups, function( key, value ) { - if ( typeof value === "string" ) { - value = value.split(/\s/); - } - $.each(value, function( index, name ) { - groups[name] = key; - }); - }); - var rules = this.settings.rules; - $.each(rules, function( key, value ) { - rules[key] = $.validator.normalizeRule(value); - }); - - function delegate(event) { - var validator = $.data(this[0].form, "validator"), - eventType = "on" + event.type.replace(/^validate/, ""); - if ( validator.settings[eventType] ) { - validator.settings[eventType].call(validator, this[0], event); - } - } - $(this.currentForm) - .validateDelegate(":text, [type='password'], [type='file'], select, textarea, " + - "[type='number'], [type='search'] ,[type='tel'], [type='url'], " + - "[type='email'], [type='datetime'], [type='date'], [type='month'], " + - "[type='week'], [type='time'], [type='datetime-local'], " + - "[type='range'], [type='color'] ", - "focusin focusout keyup", delegate) - .validateDelegate("[type='radio'], [type='checkbox'], select, option", "click", delegate); - - if ( this.settings.invalidHandler ) { - $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler); - } - }, - - // http://docs.jquery.com/Plugins/Validation/Validator/form - form: function() { - this.checkForm(); - $.extend(this.submitted, this.errorMap); - this.invalid = $.extend({}, this.errorMap); - if ( !this.valid() ) { - $(this.currentForm).triggerHandler("invalid-form", [this]); - } - this.showErrors(); - return this.valid(); - }, - - checkForm: function() { - this.prepareForm(); - for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) { - this.check( elements[i] ); - } - return this.valid(); - }, - - // http://docs.jquery.com/Plugins/Validation/Validator/element - element: function( element ) { - element = this.validationTargetFor( this.clean( element ) ); - this.lastElement = element; - this.prepareElement( element ); - this.currentElements = $(element); - var result = this.check( element ) !== false; - if ( result ) { - delete this.invalid[element.name]; - } else { - this.invalid[element.name] = true; - } - if ( !this.numberOfInvalids() ) { - // Hide error containers on last error - this.toHide = this.toHide.add( this.containers ); - } - this.showErrors(); - return result; - }, - - // http://docs.jquery.com/Plugins/Validation/Validator/showErrors - showErrors: function( errors ) { - if ( errors ) { - // add items to error list and map - $.extend( this.errorMap, errors ); - this.errorList = []; - for ( var name in errors ) { - this.errorList.push({ - message: errors[name], - element: this.findByName(name)[0] - }); - } - // remove items from success list - this.successList = $.grep( this.successList, function( element ) { - return !(element.name in errors); - }); - } - if ( this.settings.showErrors ) { - this.settings.showErrors.call( this, this.errorMap, this.errorList ); - } else { - this.defaultShowErrors(); - } - }, - - // http://docs.jquery.com/Plugins/Validation/Validator/resetForm - resetForm: function() { - if ( $.fn.resetForm ) { - $(this.currentForm).resetForm(); - } - this.submitted = {}; - this.lastElement = null; - this.prepareForm(); - this.hideErrors(); - this.elements().removeClass( this.settings.errorClass ).removeData( "previousValue" ); - }, - - numberOfInvalids: function() { - return this.objectLength(this.invalid); - }, - - objectLength: function( obj ) { - var count = 0; - for ( var i in obj ) { - count++; - } - return count; - }, - - hideErrors: function() { - this.addWrapper( this.toHide ).hide(); - }, - - valid: function() { - return this.size() === 0; - }, - - size: function() { - return this.errorList.length; - }, - - focusInvalid: function() { - if ( this.settings.focusInvalid ) { - try { - $(this.findLastActive() || this.errorList.length && this.errorList[0].element || []) - .filter(":visible") - .focus() - // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find - .trigger("focusin"); - } catch(e) { - // ignore IE throwing errors when focusing hidden elements - } - } - }, - - findLastActive: function() { - var lastActive = this.lastActive; - return lastActive && $.grep(this.errorList, function( n ) { - return n.element.name === lastActive.name; - }).length === 1 && lastActive; - }, - - elements: function() { - var validator = this, - rulesCache = {}; - - // select all valid inputs inside the form (no submit or reset buttons) - return $(this.currentForm) - .find("input, select, textarea") - .not(":submit, :reset, :image, [disabled]") - .not( this.settings.ignore ) - .filter(function() { - if ( !this.name ) { - if ( window.console ) { - console.error( "%o has no name assigned", this ); - } - throw new Error( "Failed to validate, found an element with no name assigned. See console for element reference." ); - } - - // select only the first element for each name, and only those with rules specified - if ( this.name in rulesCache || !validator.objectLength($(this).rules()) ) { - return false; - } - - rulesCache[this.name] = true; - return true; - }); - }, - - clean: function( selector ) { - return $(selector)[0]; - }, - - errors: function() { - var errorClass = this.settings.errorClass.replace(" ", "."); - return $(this.settings.errorElement + "." + errorClass, this.errorContext); - }, - - reset: function() { - this.successList = []; - this.errorList = []; - this.errorMap = {}; - this.toShow = $([]); - this.toHide = $([]); - this.currentElements = $([]); - }, - - prepareForm: function() { - this.reset(); - this.toHide = this.errors().add( this.containers ); - }, - - prepareElement: function( element ) { - this.reset(); - this.toHide = this.errorsFor(element); - }, - - elementValue: function( element ) { - var type = $(element).attr("type"), - val = $(element).val(); - - if ( type === "radio" || type === "checkbox" ) { - return $("input[name='" + $(element).attr("name") + "']:checked").val(); - } - - if ( typeof val === "string" ) { - return val.replace(/\r/g, ""); - } - return val; - }, - - check: function( element ) { - element = this.validationTargetFor( this.clean( element ) ); - - var rules = $(element).rules(); - var dependencyMismatch = false; - var val = this.elementValue(element); - var result; - - for (var method in rules ) { - var rule = { method: method, parameters: rules[method] }; - try { - - result = $.validator.methods[method].call( this, val, element, rule.parameters ); - - // if a method indicates that the field is optional and therefore valid, - // don't mark it as valid when there are no other rules - if ( result === "dependency-mismatch" ) { - dependencyMismatch = true; - continue; - } - dependencyMismatch = false; - - if ( result === "pending" ) { - this.toHide = this.toHide.not( this.errorsFor(element) ); - return; - } - - if ( !result ) { - this.formatAndAdd( element, rule ); - return false; - } - } catch(e) { - if ( this.settings.debug && window.console ) { - console.log( "Exception occured when checking element " + element.id + ", check the '" + rule.method + "' method.", e ); - } - throw e; - } - } - if ( dependencyMismatch ) { - return; - } - if ( this.objectLength(rules) ) { - this.successList.push(element); - } - return true; - }, - - // return the custom message for the given element and validation method - // specified in the element's HTML5 data attribute - customDataMessage: function( element, method ) { - return $(element).data("msg-" + method.toLowerCase()) || (element.attributes && $(element).attr("data-msg-" + method.toLowerCase())); - }, - - // return the custom message for the given element name and validation method - customMessage: function( name, method ) { - var m = this.settings.messages[name]; - return m && (m.constructor === String ? m : m[method]); - }, - - // return the first defined argument, allowing empty strings - findDefined: function() { - for(var i = 0; i < arguments.length; i++) { - if ( arguments[i] !== undefined ) { - return arguments[i]; - } - } - return undefined; - }, - - defaultMessage: function( element, method ) { - return this.findDefined( - this.customMessage( element.name, method ), - this.customDataMessage( element, method ), - // title is never undefined, so handle empty string as undefined - !this.settings.ignoreTitle && element.title || undefined, - $.validator.messages[method], - "Warning: No message defined for " + element.name + "" - ); - }, - - formatAndAdd: function( element, rule ) { - var message = this.defaultMessage( element, rule.method ), - theregex = /\$?\{(\d+)\}/g; - if ( typeof message === "function" ) { - message = message.call(this, rule.parameters, element); - } else if (theregex.test(message)) { - message = $.validator.format(message.replace(theregex, "{$1}"), rule.parameters); - } - this.errorList.push({ - message: message, - element: element - }); - - this.errorMap[element.name] = message; - this.submitted[element.name] = message; - }, - - addWrapper: function( toToggle ) { - if ( this.settings.wrapper ) { - toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) ); - } - return toToggle; - }, - - defaultShowErrors: function() { - var i, elements; - for ( i = 0; this.errorList[i]; i++ ) { - var error = this.errorList[i]; - if ( this.settings.highlight ) { - this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass ); - } - this.showLabel( error.element, error.message ); - } - if ( this.errorList.length ) { - this.toShow = this.toShow.add( this.containers ); - } - if ( this.settings.success ) { - for ( i = 0; this.successList[i]; i++ ) { - this.showLabel( this.successList[i] ); - } - } - if ( this.settings.unhighlight ) { - for ( i = 0, elements = this.validElements(); elements[i]; i++ ) { - this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass ); - } - } - this.toHide = this.toHide.not( this.toShow ); - this.hideErrors(); - this.addWrapper( this.toShow ).show(); - }, - - validElements: function() { - return this.currentElements.not(this.invalidElements()); - }, - - invalidElements: function() { - return $(this.errorList).map(function() { - return this.element; - }); - }, - - showLabel: function( element, message ) { - var label = this.errorsFor( element ); - if ( label.length ) { - // refresh error/success class - label.removeClass( this.settings.validClass ).addClass( this.settings.errorClass ); - - // check if we have a generated label, replace the message then - if ( label.attr("generated") ) { - label.html(message); - } - } else { - // create label - label = $("<" + this.settings.errorElement + "/>") - .attr({"for": this.idOrName(element), generated: true}) - .addClass(this.settings.errorClass) - .html(message || ""); - if ( this.settings.wrapper ) { - // make sure the element is visible, even in IE - // actually showing the wrapped element is handled elsewhere - label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent(); - } - if ( !this.labelContainer.append(label).length ) { - if ( this.settings.errorPlacement ) { - this.settings.errorPlacement(label, $(element) ); - } else { - label.insertAfter(element); - } - } - } - if ( !message && this.settings.success ) { - label.text(""); - if ( typeof this.settings.success === "string" ) { - label.addClass( this.settings.success ); - } else { - this.settings.success( label, element ); - } - } - this.toShow = this.toShow.add(label); - }, - - errorsFor: function( element ) { - var name = this.idOrName(element); - return this.errors().filter(function() { - return $(this).attr("for") === name; - }); - }, - - idOrName: function( element ) { - return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name); - }, - - validationTargetFor: function( element ) { - // if radio/checkbox, validate first element in group instead - if ( this.checkable(element) ) { - element = this.findByName( element.name ).not(this.settings.ignore)[0]; - } - return element; - }, - - checkable: function( element ) { - return (/radio|checkbox/i).test(element.type); - }, - - findByName: function( name ) { - return $(this.currentForm).find("[name='" + name + "']"); - }, - - getLength: function( value, element ) { - switch( element.nodeName.toLowerCase() ) { - case "select": - return $("option:selected", element).length; - case "input": - if ( this.checkable( element) ) { - return this.findByName(element.name).filter(":checked").length; - } - } - return value.length; - }, - - depend: function( param, element ) { - return this.dependTypes[typeof param] ? this.dependTypes[typeof param](param, element) : true; - }, - - dependTypes: { - "boolean": function( param, element ) { - return param; - }, - "string": function( param, element ) { - return !!$(param, element.form).length; - }, - "function": function( param, element ) { - return param(element); - } - }, - - optional: function( element ) { - var val = this.elementValue(element); - return !$.validator.methods.required.call(this, val, element) && "dependency-mismatch"; - }, - - startRequest: function( element ) { - if ( !this.pending[element.name] ) { - this.pendingRequest++; - this.pending[element.name] = true; - } - }, - - stopRequest: function( element, valid ) { - this.pendingRequest--; - // sometimes synchronization fails, make sure pendingRequest is never < 0 - if ( this.pendingRequest < 0 ) { - this.pendingRequest = 0; - } - delete this.pending[element.name]; - if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) { - $(this.currentForm).submit(); - this.formSubmitted = false; - } else if (!valid && this.pendingRequest === 0 && this.formSubmitted) { - $(this.currentForm).triggerHandler("invalid-form", [this]); - this.formSubmitted = false; - } - }, - - previousValue: function( element ) { - return $.data(element, "previousValue") || $.data(element, "previousValue", { - old: null, - valid: true, - message: this.defaultMessage( element, "remote" ) - }); - } - - }, - - classRuleSettings: { - required: {required: true}, - email: {email: true}, - url: {url: true}, - date: {date: true}, - dateISO: {dateISO: true}, - number: {number: true}, - digits: {digits: true}, - creditcard: {creditcard: true} - }, - - addClassRules: function( className, rules ) { - if ( className.constructor === String ) { - this.classRuleSettings[className] = rules; - } else { - $.extend(this.classRuleSettings, className); - } - }, - - classRules: function( element ) { - var rules = {}; - var classes = $(element).attr("class"); - if ( classes ) { - $.each(classes.split(" "), function() { - if ( this in $.validator.classRuleSettings ) { - $.extend(rules, $.validator.classRuleSettings[this]); - } - }); - } - return rules; - }, - - attributeRules: function( element ) { - var rules = {}; - var $element = $(element); - - for (var method in $.validator.methods) { - var value; - - // support for in both html5 and older browsers - if ( method === "required" ) { - value = $element.get(0).getAttribute(method); - // Some browsers return an empty string for the required attribute - // and non-HTML5 browsers might have required="" markup - if ( value === "" ) { - value = true; - } - // force non-HTML5 browsers to return bool - value = !!value; - } else { - value = $element.attr(method); - } - - if ( value ) { - rules[method] = value; - } else if ( $element[0].getAttribute("type") === method ) { - rules[method] = true; - } - } - - // maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs - if ( rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength) ) { - delete rules.maxlength; - } - - return rules; - }, - - dataRules: function( element ) { - var method, value, - rules = {}, $element = $(element); - for (method in $.validator.methods) { - value = $element.data("rule-" + method.toLowerCase()); - if ( value !== undefined ) { - rules[method] = value; - } - } - return rules; - }, - - staticRules: function( element ) { - var rules = {}; - var validator = $.data(element.form, "validator"); - if ( validator.settings.rules ) { - rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {}; - } - return rules; - }, - - normalizeRules: function( rules, element ) { - // handle dependency check - $.each(rules, function( prop, val ) { - // ignore rule when param is explicitly false, eg. required:false - if ( val === false ) { - delete rules[prop]; - return; - } - if ( val.param || val.depends ) { - var keepRule = true; - switch (typeof val.depends) { - case "string": - keepRule = !!$(val.depends, element.form).length; - break; - case "function": - keepRule = val.depends.call(element, element); - break; - } - if ( keepRule ) { - rules[prop] = val.param !== undefined ? val.param : true; - } else { - delete rules[prop]; - } - } - }); - - // evaluate parameters - $.each(rules, function( rule, parameter ) { - rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter; - }); - - // clean number parameters - $.each(["minlength", "maxlength", "min", "max"], function() { - if ( rules[this] ) { - rules[this] = Number(rules[this]); - } - }); - $.each(["rangelength", "range"], function() { - var parts; - if ( rules[this] ) { - if ( $.isArray(rules[this]) ) { - rules[this] = [Number(rules[this][0]), Number(rules[this][1])]; - } else if ( typeof rules[this] === "string" ) { - parts = rules[this].split(/[\s,]+/); - rules[this] = [Number(parts[0]), Number(parts[1])]; - } - } - }); - - if ( $.validator.autoCreateRanges ) { - // auto-create ranges - if ( rules.min && rules.max ) { - rules.range = [rules.min, rules.max]; - delete rules.min; - delete rules.max; - } - if ( rules.minlength && rules.maxlength ) { - rules.rangelength = [rules.minlength, rules.maxlength]; - delete rules.minlength; - delete rules.maxlength; - } - } - - return rules; - }, - - // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true} - normalizeRule: function( data ) { - if ( typeof data === "string" ) { - var transformed = {}; - $.each(data.split(/\s/), function() { - transformed[this] = true; - }); - data = transformed; - } - return data; - }, - - // http://docs.jquery.com/Plugins/Validation/Validator/addMethod - addMethod: function( name, method, message ) { - $.validator.methods[name] = method; - $.validator.messages[name] = message !== undefined ? message : $.validator.messages[name]; - if ( method.length < 3 ) { - $.validator.addClassRules(name, $.validator.normalizeRule(name)); - } - }, - - methods: { - - // http://docs.jquery.com/Plugins/Validation/Methods/required - required: function( value, element, param ) { - // check if dependency is met - if ( !this.depend(param, element) ) { - return "dependency-mismatch"; - } - if ( element.nodeName.toLowerCase() === "select" ) { - // could be an array for select-multiple or a string, both are fine this way - var val = $(element).val(); - return val && val.length > 0; - } - if ( this.checkable(element) ) { - return this.getLength(value, element) > 0; - } - return $.trim(value).length > 0; - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/remote - remote: function( value, element, param ) { - if ( this.optional(element) ) { - return "dependency-mismatch"; - } - - var previous = this.previousValue(element); - if (!this.settings.messages[element.name] ) { - this.settings.messages[element.name] = {}; - } - previous.originalMessage = this.settings.messages[element.name].remote; - this.settings.messages[element.name].remote = previous.message; - - param = typeof param === "string" && {url:param} || param; - - if ( previous.old === value ) { - return previous.valid; - } - - previous.old = value; - var validator = this; - this.startRequest(element); - var data = {}; - data[element.name] = value; - $.ajax($.extend(true, { - url: param, - mode: "abort", - port: "validate" + element.name, - dataType: "json", - data: data, - success: function( response ) { - validator.settings.messages[element.name].remote = previous.originalMessage; - var valid = response === true || response === "true"; - if ( valid ) { - var submitted = validator.formSubmitted; - validator.prepareElement(element); - validator.formSubmitted = submitted; - validator.successList.push(element); - delete validator.invalid[element.name]; - validator.showErrors(); - } else { - var errors = {}; - var message = response || validator.defaultMessage( element, "remote" ); - errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message; - validator.invalid[element.name] = true; - validator.showErrors(errors); - } - previous.valid = valid; - validator.stopRequest(element, valid); - } - }, param)); - return "pending"; - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/minlength - minlength: function( value, element, param ) { - var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element); - return this.optional(element) || length >= param; - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/maxlength - maxlength: function( value, element, param ) { - var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element); - return this.optional(element) || length <= param; - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/rangelength - rangelength: function( value, element, param ) { - var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element); - return this.optional(element) || ( length >= param[0] && length <= param[1] ); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/min - min: function( value, element, param ) { - return this.optional(element) || value >= param; - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/max - max: function( value, element, param ) { - return this.optional(element) || value <= param; - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/range - range: function( value, element, param ) { - return this.optional(element) || ( value >= param[0] && value <= param[1] ); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/email - email: function( value, element ) { - // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/ - return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/url - url: function( value, element ) { - // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/ - return this.optional(element) || /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/date - date: function( value, element ) { - return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString()); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/dateISO - dateISO: function( value, element ) { - return this.optional(element) || /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(value); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/number - number: function( value, element ) { - return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/digits - digits: function( value, element ) { - return this.optional(element) || /^\d+$/.test(value); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/creditcard - // based on http://en.wikipedia.org/wiki/Luhn - creditcard: function( value, element ) { - if ( this.optional(element) ) { - return "dependency-mismatch"; - } - // accept only spaces, digits and dashes - if ( /[^0-9 \-]+/.test(value) ) { - return false; - } - var nCheck = 0, - nDigit = 0, - bEven = false; - - value = value.replace(/\D/g, ""); - - for (var n = value.length - 1; n >= 0; n--) { - var cDigit = value.charAt(n); - nDigit = parseInt(cDigit, 10); - if ( bEven ) { - if ( (nDigit *= 2) > 9 ) { - nDigit -= 9; - } - } - nCheck += nDigit; - bEven = !bEven; - } - - return (nCheck % 10) === 0; - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/equalTo - equalTo: function( value, element, param ) { - // bind to the blur event of the target in order to revalidate whenever the target field is updated - // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead - var target = $(param); - if ( this.settings.onfocusout ) { - target.unbind(".validate-equalTo").bind("blur.validate-equalTo", function() { - $(element).valid(); - }); - } - return value === target.val(); - } - - } - -}); + $.validator = function (options, form) { + this.settings = $.extend(true, {}, $.validator.defaults, options); + this.currentForm = form; + this.init(); + }; + + $.validator.format = function (source, params) { + if (arguments.length === 1) { + return function () { + var args = $.makeArray(arguments); + args.unshift(source); + return $.validator.format.apply(this, args); + }; + } + if (arguments.length > 2 && params.constructor !== Array) { + params = $.makeArray(arguments).slice(1); + } + if (params.constructor !== Array) { + params = [params]; + } + $.each(params, function (i, n) { + source = source.replace(new RegExp("\\{" + i + "\\}", "g"), function () { + return n; + }); + }); + return source; + }; + + $.extend($.validator, { + + defaults: { + messages: {}, + groups: {}, + rules: {}, + errorClass: "error", + validClass: "valid", + errorElement: "label", + focusInvalid: true, + errorContainer: $([]), + errorLabelContainer: $([]), + onsubmit: true, + ignore: ":hidden", + ignoreTitle: false, + onfocusin: function (element, event) { + this.lastActive = element; + + // hide error label and remove error class on focus if enabled + if (this.settings.focusCleanup && !this.blockFocusCleanup) { + if (this.settings.unhighlight) { + this.settings.unhighlight.call(this, element, this.settings.errorClass, this.settings.validClass); + } + this.addWrapper(this.errorsFor(element)).hide(); + } + }, + onfocusout: function (element, event) { + if (!this.checkable(element) && (element.name in this.submitted || !this.optional(element))) { + this.element(element); + } + }, + onkeyup: function (element, event) { + if (event.which === 9 && this.elementValue(element) === "") { + return; + } else if (element.name in this.submitted || element === this.lastElement) { + this.element(element); + } + }, + onclick: function (element, event) { + // click on selects, radiobuttons and checkboxes + if (element.name in this.submitted) { + this.element(element); + } + // or option elements, check parent select in that case + else if (element.parentNode.name in this.submitted) { + this.element(element.parentNode); + } + }, + highlight: function (element, errorClass, validClass) { + if (element.type === "radio") { + this.findByName(element.name).addClass(errorClass).removeClass(validClass); + } else { + $(element).addClass(errorClass).removeClass(validClass); + } + }, + unhighlight: function (element, errorClass, validClass) { + if (element.type === "radio") { + this.findByName(element.name).removeClass(errorClass).addClass(validClass); + } else { + $(element).removeClass(errorClass).addClass(validClass); + } + } + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults + setDefaults: function (settings) { + $.extend($.validator.defaults, settings); + }, + + messages: { + required: "This field is required.", + remote: "Please fix this field.", + email: "Please enter a valid email address.", + url: "Please enter a valid URL.", + date: "Please enter a valid date.", + dateISO: "Please enter a valid date (ISO).", + number: "Please enter a valid number.", + digits: "Please enter only digits.", + creditcard: "Please enter a valid credit card number.", + equalTo: "Please enter the same value again.", + maxlength: $.validator.format("Please enter no more than {0} characters."), + minlength: $.validator.format("Please enter at least {0} characters."), + rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."), + range: $.validator.format("Please enter a value between {0} and {1}."), + max: $.validator.format("Please enter a value less than or equal to {0}."), + min: $.validator.format("Please enter a value greater than or equal to {0}.") + }, + + autoCreateRanges: false, + + prototype: { + + init: function () { + this.labelContainer = $(this.settings.errorLabelContainer); + this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm); + this.containers = $(this.settings.errorContainer).add(this.settings.errorLabelContainer); + this.submitted = {}; + this.valueCache = {}; + this.pendingRequest = 0; + this.pending = {}; + this.invalid = {}; + this.reset(); + + var groups = (this.groups = {}); + $.each(this.settings.groups, function (key, value) { + if (typeof value === "string") { + value = value.split(/\s/); + } + $.each(value, function (index, name) { + groups[name] = key; + }); + }); + var rules = this.settings.rules; + $.each(rules, function (key, value) { + rules[key] = $.validator.normalizeRule(value); + }); + + function delegate(event) { + var validator = $.data(this[0].form, "validator"), + eventType = "on" + event.type.replace(/^validate/, ""); + if (validator.settings[eventType]) { + validator.settings[eventType].call(validator, this[0], event); + } + } + + $(this.currentForm) + .validateDelegate(":text, [type='password'], [type='file'], select, textarea, " + + "[type='number'], [type='search'] ,[type='tel'], [type='url'], " + + "[type='email'], [type='datetime'], [type='date'], [type='month'], " + + "[type='week'], [type='time'], [type='datetime-local'], " + + "[type='range'], [type='color'] ", + "focusin focusout keyup", delegate) + .validateDelegate("[type='radio'], [type='checkbox'], select, option", "click", delegate); + + if (this.settings.invalidHandler) { + $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler); + } + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/form + form: function () { + this.checkForm(); + $.extend(this.submitted, this.errorMap); + this.invalid = $.extend({}, this.errorMap); + if (!this.valid()) { + $(this.currentForm).triggerHandler("invalid-form", [this]); + } + this.showErrors(); + return this.valid(); + }, + + checkForm: function () { + this.prepareForm(); + for (var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++) { + this.check(elements[i]); + } + return this.valid(); + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/element + element: function (element) { + element = this.validationTargetFor(this.clean(element)); + this.lastElement = element; + this.prepareElement(element); + this.currentElements = $(element); + var result = this.check(element) !== false; + if (result) { + delete this.invalid[element.name]; + } else { + this.invalid[element.name] = true; + } + if (!this.numberOfInvalids()) { + // Hide error containers on last error + this.toHide = this.toHide.add(this.containers); + } + this.showErrors(); + return result; + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/showErrors + showErrors: function (errors) { + if (errors) { + // add items to error list and map + $.extend(this.errorMap, errors); + this.errorList = []; + for (var name in errors) { + this.errorList.push({ + message: errors[name], + element: this.findByName(name)[0] + }); + } + // remove items from success list + this.successList = $.grep(this.successList, function (element) { + return !(element.name in errors); + }); + } + if (this.settings.showErrors) { + this.settings.showErrors.call(this, this.errorMap, this.errorList); + } else { + this.defaultShowErrors(); + } + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/resetForm + resetForm: function () { + if ($.fn.resetForm) { + $(this.currentForm).resetForm(); + } + this.submitted = {}; + this.lastElement = null; + this.prepareForm(); + this.hideErrors(); + this.elements().removeClass(this.settings.errorClass).removeData("previousValue"); + }, + + numberOfInvalids: function () { + return this.objectLength(this.invalid); + }, + + objectLength: function (obj) { + var count = 0; + for (var i in obj) { + count++; + } + return count; + }, + + hideErrors: function () { + this.addWrapper(this.toHide).hide(); + }, + + valid: function () { + return this.size() === 0; + }, + + size: function () { + return this.errorList.length; + }, + + focusInvalid: function () { + if (this.settings.focusInvalid) { + try { + $(this.findLastActive() || this.errorList.length && this.errorList[0].element || []) + .filter(":visible") + .focus() + // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find + .trigger("focusin"); + } catch (e) { + // ignore IE throwing errors when focusing hidden elements + } + } + }, + + findLastActive: function () { + var lastActive = this.lastActive; + return lastActive && $.grep(this.errorList, function (n) { + return n.element.name === lastActive.name; + }).length === 1 && lastActive; + }, + + elements: function () { + var validator = this, + rulesCache = {}; + + // select all valid inputs inside the form (no submit or reset buttons) + return $(this.currentForm) + .find("input, select, textarea") + .not(":submit, :reset, :image, [disabled]") + .not(this.settings.ignore) + .filter(function () { + if (!this.name) { + if (window.console) { + console.error("%o has no name assigned", this); + } + throw new Error("Failed to validate, found an element with no name assigned. See console for element reference."); + } + + // select only the first element for each name, and only those with rules specified + if (this.name in rulesCache || !validator.objectLength($(this).rules())) { + return false; + } + + rulesCache[this.name] = true; + return true; + }); + }, + + clean: function (selector) { + return $(selector)[0]; + }, + + errors: function () { + var errorClass = this.settings.errorClass.replace(" ", "."); + return $(this.settings.errorElement + "." + errorClass, this.errorContext); + }, + + reset: function () { + this.successList = []; + this.errorList = []; + this.errorMap = {}; + this.toShow = $([]); + this.toHide = $([]); + this.currentElements = $([]); + }, + + prepareForm: function () { + this.reset(); + this.toHide = this.errors().add(this.containers); + }, + + prepareElement: function (element) { + this.reset(); + this.toHide = this.errorsFor(element); + }, + + elementValue: function (element) { + var type = $(element).attr("type"), + val = $(element).val(); + + if (type === "radio" || type === "checkbox") { + return $("input[name='" + $(element).attr("name") + "']:checked").val(); + } + + if (typeof val === "string") { + return val.replace(/\r/g, ""); + } + return val; + }, + + check: function (element) { + element = this.validationTargetFor(this.clean(element)); + + var rules = $(element).rules(); + var dependencyMismatch = false; + var val = this.elementValue(element); + var result; + + for (var method in rules) { + var rule = {method: method, parameters: rules[method]}; + try { + + result = $.validator.methods[method].call(this, val, element, rule.parameters); + + // if a method indicates that the field is optional and therefore valid, + // don't mark it as valid when there are no other rules + if (result === "dependency-mismatch") { + dependencyMismatch = true; + continue; + } + dependencyMismatch = false; + + if (result === "pending") { + this.toHide = this.toHide.not(this.errorsFor(element)); + return; + } + + if (!result) { + this.formatAndAdd(element, rule); + return false; + } + } catch (e) { + if (this.settings.debug && window.console) { + console.log("Exception occured when checking element " + element.id + ", check the '" + rule.method + "' method.", e); + } + throw e; + } + } + if (dependencyMismatch) { + return; + } + if (this.objectLength(rules)) { + this.successList.push(element); + } + return true; + }, + + // return the custom message for the given element and validation method + // specified in the element's HTML5 data attribute + customDataMessage: function (element, method) { + return $(element).data("msg-" + method.toLowerCase()) || (element.attributes && $(element).attr("data-msg-" + method.toLowerCase())); + }, + + // return the custom message for the given element name and validation method + customMessage: function (name, method) { + var m = this.settings.messages[name]; + return m && (m.constructor === String ? m : m[method]); + }, + + // return the first defined argument, allowing empty strings + findDefined: function () { + for (var i = 0; i < arguments.length; i++) { + if (arguments[i] !== undefined) { + return arguments[i]; + } + } + return undefined; + }, + + defaultMessage: function (element, method) { + return this.findDefined( + this.customMessage(element.name, method), + this.customDataMessage(element, method), + // title is never undefined, so handle empty string as undefined + !this.settings.ignoreTitle && element.title || undefined, + $.validator.messages[method], + "Warning: No message defined for " + element.name + "" + ); + }, + + formatAndAdd: function (element, rule) { + var message = this.defaultMessage(element, rule.method), + theregex = /\$?\{(\d+)\}/g; + if (typeof message === "function") { + message = message.call(this, rule.parameters, element); + } else if (theregex.test(message)) { + message = $.validator.format(message.replace(theregex, "{$1}"), rule.parameters); + } + this.errorList.push({ + message: message, + element: element + }); + + this.errorMap[element.name] = message; + this.submitted[element.name] = message; + }, + + addWrapper: function (toToggle) { + if (this.settings.wrapper) { + toToggle = toToggle.add(toToggle.parent(this.settings.wrapper)); + } + return toToggle; + }, + + defaultShowErrors: function () { + var i, elements; + for (i = 0; this.errorList[i]; i++) { + var error = this.errorList[i]; + if (this.settings.highlight) { + this.settings.highlight.call(this, error.element, this.settings.errorClass, this.settings.validClass); + } + this.showLabel(error.element, error.message); + } + if (this.errorList.length) { + this.toShow = this.toShow.add(this.containers); + } + if (this.settings.success) { + for (i = 0; this.successList[i]; i++) { + this.showLabel(this.successList[i]); + } + } + if (this.settings.unhighlight) { + for (i = 0, elements = this.validElements(); elements[i]; i++) { + this.settings.unhighlight.call(this, elements[i], this.settings.errorClass, this.settings.validClass); + } + } + this.toHide = this.toHide.not(this.toShow); + this.hideErrors(); + this.addWrapper(this.toShow).show(); + }, + + validElements: function () { + return this.currentElements.not(this.invalidElements()); + }, + + invalidElements: function () { + return $(this.errorList).map(function () { + return this.element; + }); + }, + + showLabel: function (element, message) { + var label = this.errorsFor(element); + if (label.length) { + // refresh error/success class + label.removeClass(this.settings.validClass).addClass(this.settings.errorClass); + + // check if we have a generated label, replace the message then + if (label.attr("generated")) { + label.html(message); + } + } else { + // create label + label = $("<" + this.settings.errorElement + "/>") + .attr({"for": this.idOrName(element), generated: true}) + .addClass(this.settings.errorClass) + .html(message || ""); + if (this.settings.wrapper) { + // make sure the element is visible, even in IE + // actually showing the wrapped element is handled elsewhere + label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent(); + } + if (!this.labelContainer.append(label).length) { + if (this.settings.errorPlacement) { + this.settings.errorPlacement(label, $(element)); + } else { + label.insertAfter(element); + } + } + } + if (!message && this.settings.success) { + label.text(""); + if (typeof this.settings.success === "string") { + label.addClass(this.settings.success); + } else { + this.settings.success(label, element); + } + } + this.toShow = this.toShow.add(label); + }, + + errorsFor: function (element) { + var name = this.idOrName(element); + return this.errors().filter(function () { + return $(this).attr("for") === name; + }); + }, + + idOrName: function (element) { + return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name); + }, + + validationTargetFor: function (element) { + // if radio/checkbox, validate first element in group instead + if (this.checkable(element)) { + element = this.findByName(element.name).not(this.settings.ignore)[0]; + } + return element; + }, + + checkable: function (element) { + return (/radio|checkbox/i).test(element.type); + }, + + findByName: function (name) { + return $(this.currentForm).find("[name='" + name + "']"); + }, + + getLength: function (value, element) { + switch (element.nodeName.toLowerCase()) { + case "select": + return $("option:selected", element).length; + case "input": + if (this.checkable(element)) { + return this.findByName(element.name).filter(":checked").length; + } + } + return value.length; + }, + + depend: function (param, element) { + return this.dependTypes[typeof param] ? this.dependTypes[typeof param](param, element) : true; + }, + + dependTypes: { + "boolean": function (param, element) { + return param; + }, + "string": function (param, element) { + return !!$(param, element.form).length; + }, + "function": function (param, element) { + return param(element); + } + }, + + optional: function (element) { + var val = this.elementValue(element); + return !$.validator.methods.required.call(this, val, element) && "dependency-mismatch"; + }, + + startRequest: function (element) { + if (!this.pending[element.name]) { + this.pendingRequest++; + this.pending[element.name] = true; + } + }, + + stopRequest: function (element, valid) { + this.pendingRequest--; + // sometimes synchronization fails, make sure pendingRequest is never < 0 + if (this.pendingRequest < 0) { + this.pendingRequest = 0; + } + delete this.pending[element.name]; + if (valid && this.pendingRequest === 0 && this.formSubmitted && this.form()) { + $(this.currentForm).submit(); + this.formSubmitted = false; + } else if (!valid && this.pendingRequest === 0 && this.formSubmitted) { + $(this.currentForm).triggerHandler("invalid-form", [this]); + this.formSubmitted = false; + } + }, + + previousValue: function (element) { + return $.data(element, "previousValue") || $.data(element, "previousValue", { + old: null, + valid: true, + message: this.defaultMessage(element, "remote") + }); + } + + }, + + classRuleSettings: { + required: {required: true}, + email: {email: true}, + url: {url: true}, + date: {date: true}, + dateISO: {dateISO: true}, + number: {number: true}, + digits: {digits: true}, + creditcard: {creditcard: true} + }, + + addClassRules: function (className, rules) { + if (className.constructor === String) { + this.classRuleSettings[className] = rules; + } else { + $.extend(this.classRuleSettings, className); + } + }, + + classRules: function (element) { + var rules = {}; + var classes = $(element).attr("class"); + if (classes) { + $.each(classes.split(" "), function () { + if (this in $.validator.classRuleSettings) { + $.extend(rules, $.validator.classRuleSettings[this]); + } + }); + } + return rules; + }, + + attributeRules: function (element) { + var rules = {}; + var $element = $(element); + + for (var method in $.validator.methods) { + var value; + + // support for in both html5 and older browsers + if (method === "required") { + value = $element.get(0).getAttribute(method); + // Some browsers return an empty string for the required attribute + // and non-HTML5 browsers might have required="" markup + if (value === "") { + value = true; + } + // force non-HTML5 browsers to return bool + value = !!value; + } else { + value = $element.attr(method); + } + + if (value) { + rules[method] = value; + } else if ($element[0].getAttribute("type") === method) { + rules[method] = true; + } + } + + // maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs + if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) { + delete rules.maxlength; + } + + return rules; + }, + + dataRules: function (element) { + var method, value, + rules = {}, $element = $(element); + for (method in $.validator.methods) { + value = $element.data("rule-" + method.toLowerCase()); + if (value !== undefined) { + rules[method] = value; + } + } + return rules; + }, + + staticRules: function (element) { + var rules = {}; + var validator = $.data(element.form, "validator"); + if (validator.settings.rules) { + rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {}; + } + return rules; + }, + + normalizeRules: function (rules, element) { + // handle dependency check + $.each(rules, function (prop, val) { + // ignore rule when param is explicitly false, eg. required:false + if (val === false) { + delete rules[prop]; + return; + } + if (val.param || val.depends) { + var keepRule = true; + switch (typeof val.depends) { + case "string": + keepRule = !!$(val.depends, element.form).length; + break; + case "function": + keepRule = val.depends.call(element, element); + break; + } + if (keepRule) { + rules[prop] = val.param !== undefined ? val.param : true; + } else { + delete rules[prop]; + } + } + }); + + // evaluate parameters + $.each(rules, function (rule, parameter) { + rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter; + }); + + // clean number parameters + $.each(["minlength", "maxlength", "min", "max"], function () { + if (rules[this]) { + rules[this] = Number(rules[this]); + } + }); + $.each(["rangelength", "range"], function () { + var parts; + if (rules[this]) { + if ($.isArray(rules[this])) { + rules[this] = [Number(rules[this][0]), Number(rules[this][1])]; + } else if (typeof rules[this] === "string") { + parts = rules[this].split(/[\s,]+/); + rules[this] = [Number(parts[0]), Number(parts[1])]; + } + } + }); + + if ($.validator.autoCreateRanges) { + // auto-create ranges + if (rules.min && rules.max) { + rules.range = [rules.min, rules.max]; + delete rules.min; + delete rules.max; + } + if (rules.minlength && rules.maxlength) { + rules.rangelength = [rules.minlength, rules.maxlength]; + delete rules.minlength; + delete rules.maxlength; + } + } + + return rules; + }, + + // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true} + normalizeRule: function (data) { + if (typeof data === "string") { + var transformed = {}; + $.each(data.split(/\s/), function () { + transformed[this] = true; + }); + data = transformed; + } + return data; + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/addMethod + addMethod: function (name, method, message) { + $.validator.methods[name] = method; + $.validator.messages[name] = message !== undefined ? message : $.validator.messages[name]; + if (method.length < 3) { + $.validator.addClassRules(name, $.validator.normalizeRule(name)); + } + }, + + methods: { + + // http://docs.jquery.com/Plugins/Validation/Methods/required + required: function (value, element, param) { + // check if dependency is met + if (!this.depend(param, element)) { + return "dependency-mismatch"; + } + if (element.nodeName.toLowerCase() === "select") { + // could be an array for select-multiple or a string, both are fine this way + var val = $(element).val(); + return val && val.length > 0; + } + if (this.checkable(element)) { + return this.getLength(value, element) > 0; + } + return $.trim(value).length > 0; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/remote + remote: function (value, element, param) { + if (this.optional(element)) { + return "dependency-mismatch"; + } + + var previous = this.previousValue(element); + if (!this.settings.messages[element.name]) { + this.settings.messages[element.name] = {}; + } + previous.originalMessage = this.settings.messages[element.name].remote; + this.settings.messages[element.name].remote = previous.message; + + param = typeof param === "string" && {url: param} || param; + + if (previous.old === value) { + return previous.valid; + } + + previous.old = value; + var validator = this; + this.startRequest(element); + var data = {}; + data[element.name] = value; + $.ajax($.extend(true, { + url: param, + mode: "abort", + port: "validate" + element.name, + dataType: "json", + data: data, + success: function (response) { + validator.settings.messages[element.name].remote = previous.originalMessage; + var valid = response === true || response === "true"; + if (valid) { + var submitted = validator.formSubmitted; + validator.prepareElement(element); + validator.formSubmitted = submitted; + validator.successList.push(element); + delete validator.invalid[element.name]; + validator.showErrors(); + } else { + var errors = {}; + var message = response || validator.defaultMessage(element, "remote"); + errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message; + validator.invalid[element.name] = true; + validator.showErrors(errors); + } + previous.valid = valid; + validator.stopRequest(element, valid); + } + }, param)); + return "pending"; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/minlength + minlength: function (value, element, param) { + var length = $.isArray(value) ? value.length : this.getLength($.trim(value), element); + return this.optional(element) || length >= param; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/maxlength + maxlength: function (value, element, param) { + var length = $.isArray(value) ? value.length : this.getLength($.trim(value), element); + return this.optional(element) || length <= param; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/rangelength + rangelength: function (value, element, param) { + var length = $.isArray(value) ? value.length : this.getLength($.trim(value), element); + return this.optional(element) || ( length >= param[0] && length <= param[1] ); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/min + min: function (value, element, param) { + return this.optional(element) || value >= param; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/max + max: function (value, element, param) { + return this.optional(element) || value <= param; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/range + range: function (value, element, param) { + return this.optional(element) || ( value >= param[0] && value <= param[1] ); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/email + email: function (value, element) { + // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/ + return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/url + url: function (value, element) { + // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/ + return this.optional(element) || /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/date + date: function (value, element) { + return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString()); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/dateISO + dateISO: function (value, element) { + return this.optional(element) || /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/number + number: function (value, element) { + return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/digits + digits: function (value, element) { + return this.optional(element) || /^\d+$/.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/creditcard + // based on http://en.wikipedia.org/wiki/Luhn + creditcard: function (value, element) { + if (this.optional(element)) { + return "dependency-mismatch"; + } + // accept only spaces, digits and dashes + if (/[^0-9 \-]+/.test(value)) { + return false; + } + var nCheck = 0, + nDigit = 0, + bEven = false; + + value = value.replace(/\D/g, ""); + + for (var n = value.length - 1; n >= 0; n--) { + var cDigit = value.charAt(n); + nDigit = parseInt(cDigit, 10); + if (bEven) { + if ((nDigit *= 2) > 9) { + nDigit -= 9; + } + } + nCheck += nDigit; + bEven = !bEven; + } + + return (nCheck % 10) === 0; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/equalTo + equalTo: function (value, element, param) { + // bind to the blur event of the target in order to revalidate whenever the target field is updated + // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead + var target = $(param); + if (this.settings.onfocusout) { + target.unbind(".validate-equalTo").bind("blur.validate-equalTo", function () { + $(element).valid(); + }); + } + return value === target.val(); + } + + } + + }); // deprecated, use $.validator.format instead -$.format = $.validator.format; + $.format = $.validator.format; }(jQuery)); // ajax mode: abort // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() -(function($) { - var pendingRequests = {}; - // Use a prefilter if available (1.5+) - if ( $.ajaxPrefilter ) { - $.ajaxPrefilter(function( settings, _, xhr ) { - var port = settings.port; - if ( settings.mode === "abort" ) { - if ( pendingRequests[port] ) { - pendingRequests[port].abort(); - } - pendingRequests[port] = xhr; - } - }); - } else { - // Proxy ajax - var ajax = $.ajax; - $.ajax = function( settings ) { - var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode, - port = ( "port" in settings ? settings : $.ajaxSettings ).port; - if ( mode === "abort" ) { - if ( pendingRequests[port] ) { - pendingRequests[port].abort(); - } - return (pendingRequests[port] = ajax.apply(this, arguments)); - } - return ajax.apply(this, arguments); - }; - } +(function ($) { + var pendingRequests = {}; + // Use a prefilter if available (1.5+) + if ($.ajaxPrefilter) { + $.ajaxPrefilter(function (settings, _, xhr) { + var port = settings.port; + if (settings.mode === "abort") { + if (pendingRequests[port]) { + pendingRequests[port].abort(); + } + pendingRequests[port] = xhr; + } + }); + } else { + // Proxy ajax + var ajax = $.ajax; + $.ajax = function (settings) { + var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode, + port = ( "port" in settings ? settings : $.ajaxSettings ).port; + if (mode === "abort") { + if (pendingRequests[port]) { + pendingRequests[port].abort(); + } + return (pendingRequests[port] = ajax.apply(this, arguments)); + } + return ajax.apply(this, arguments); + }; + } }(jQuery)); // provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation // handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target -(function($) { - $.extend($.fn, { - validateDelegate: function( delegate, type, handler ) { - return this.bind(type, function( event ) { - var target = $(event.target); - if ( target.is(delegate) ) { - return handler.apply(target, arguments); - } - }); - } - }); +(function ($) { + $.extend($.fn, { + validateDelegate: function (delegate, type, handler) { + return this.bind(type, function (event) { + var target = $(event.target); + if (target.is(delegate)) { + return handler.apply(target, arguments); + } + }); + } + }); }(jQuery)); diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/type-view.hbs b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/type-view.hbs index 437d5400a..bac2a4b1c 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/type-view.hbs +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/type-view.hbs @@ -32,31 +32,31 @@

    What it Does


    Connect Arduino UNO board to WSO2 IoT Server and visualize sensor - data.

    + data.


    What You Need


    • ITEM 01 - Arduino UNO Board. + Arduino UNO Board.
    • ITEM 02 - Adafruit Wifi Shield for Arduino. + Adafruit Wifi Shield for Arduino.
    • ITEM 03 - LED bulb connected to Pin 13. + LED bulb connected to Pin 13. (If not available, will use the one on the board.)
    • ITEM 04 - Resister( e.g 330 ohms ) + Resister( e.g 330 ohms )
    • STEP 05 - Proceed to [Prepare] section. + Proceed to [Prepare] section.

    Download Sketch + {{#if displayStatus}} + Deploy Analytics Artifacts + {{/if}} + @@ -197,11 +202,11 @@
    @@ -263,17 +268,17 @@
    @@ -291,6 +296,27 @@ + + {{#zone "topCss"}} {{css "css/styles.css"}} {{/zone}} diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/type-view.js b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/type-view.js new file mode 100644 index 000000000..efb12da30 --- /dev/null +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/type-view.js @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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. + */ + +function onRequest(context) { + var viewModel = {}; + var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"]; + var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"]; + var url = devicemgtProps["httpsURL"] + "/api/device-mgt/v1.0/admin/devicetype/deploy/arduino/status"; + serviceInvokers.XMLHttp.get( + url, function (responsePayload) { + var responseContent = responsePayload.status; + new Log().error(responseContent); + if ("204" == responsePayload.status) { + viewModel["displayStatus"] = "Display"; + } + }, + function (responsePayload) { + //do nothing. + } + ); + return viewModel; +} \ No newline at end of file diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/type-view.json b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/type-view.json index 9eecd8f5b..688e93980 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/type-view.json +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.type-view/type-view.json @@ -1,3 +1,3 @@ { - "version": "1.0.0" + "version": "1.0.0" } \ No newline at end of file diff --git a/components/device-types/arduino-plugin/pom.xml b/components/device-types/arduino-plugin/pom.xml index f37fdec2a..fcc2813ba 100644 --- a/components/device-types/arduino-plugin/pom.xml +++ b/components/device-types/arduino-plugin/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.devicemgt-plugins device-types - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/device-types/pom.xml b/components/device-types/pom.xml index f64171e44..70da8b69e 100644 --- a/components/device-types/pom.xml +++ b/components/device-types/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.devicemgt-plugins carbon-device-mgt-plugins-parent - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../../pom.xml diff --git a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.analytics/pom.xml b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.analytics/pom.xml index ec0649181..f3e5511d0 100644 --- a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.analytics/pom.xml +++ b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.analytics/pom.xml @@ -21,7 +21,7 @@ raspberrypi-plugin org.wso2.carbon.devicemgt-plugins - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.analytics/src/main/resources/carbonapps/raspberrypi/raspberrypi_receiver/raspberrypi_receiver.xml b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.analytics/src/main/resources/carbonapps/raspberrypi/raspberrypi_receiver/raspberrypi_receiver.xml index 9cd4a9eb4..1424b737e 100644 --- a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.analytics/src/main/resources/carbonapps/raspberrypi/raspberrypi_receiver/raspberrypi_receiver.xml +++ b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.analytics/src/main/resources/carbonapps/raspberrypi/raspberrypi_receiver/raspberrypi_receiver.xml @@ -18,10 +18,8 @@ --> - carbon.super/raspberrypi/+/temperature - admin - admin - org.wso2.carbon.device.mgt.input.adapter.mqtt.util.MQTTContentValidator + ${tenant-domain}/raspberrypi/+/temperature + iot-mqtt true diff --git a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/pom.xml b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/pom.xml index a80de0fad..a20aa9f7f 100644 --- a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/pom.xml +++ b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/pom.xml @@ -21,7 +21,7 @@ raspberrypi-plugin org.wso2.carbon.devicemgt-plugins - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiService.java b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiService.java index 1f227e630..b048f72d5 100644 --- a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiService.java +++ b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiService.java @@ -39,7 +39,7 @@ import javax.ws.rs.core.Response; } ), tags = { - @Tag(name = "raspberrypi", description = "") + @Tag(name = "raspberrypi,device_management", description = "") } ) @Scopes( diff --git a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiServiceImpl.java b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiServiceImpl.java index c0dec9973..fdd36862a 100644 --- a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiServiceImpl.java +++ b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiServiceImpl.java @@ -141,13 +141,14 @@ public class RaspberryPiServiceImpl implements RaspberryPiService { @Produces("application/zip") public Response downloadSketch(@QueryParam("deviceName") String deviceName, @QueryParam("sketchType") String sketchType) { try { - ZipArchive zipFile = createDownloadFile(APIUtil.getAuthenticatedUser(), deviceName, sketchType); - Response.ResponseBuilder response = Response.ok(FileUtils.readFileToByteArray(zipFile.getZipFile())); + String username = APIUtil.getAuthenticatedUser() + "@" + PrivilegedCarbonContext + .getThreadLocalCarbonContext().getTenantDomain(); + ZipArchive zipFile = createDownloadFile(username, deviceName, sketchType); + Response.ResponseBuilder response = Response.ok(zipFile.getZipFileContent()); response.status(Response.Status.OK); response.type("application/zip"); response.header("Content-Disposition", "attachment; filename=\"" + zipFile.getFileName() + "\""); Response resp = response.build(); - zipFile.getZipFile().delete(); return resp; } catch (IllegalArgumentException ex) { return Response.status(400).entity(ex.getMessage()).build();//bad request @@ -160,9 +161,6 @@ public class RaspberryPiServiceImpl implements RaspberryPiService { } catch (APIManagerException ex) { log.error(ex.getMessage(), ex); return Response.status(500).entity(ex.getMessage()).build(); - } catch (IOException ex) { - log.error(ex.getMessage(), ex); - return Response.status(500).entity(ex.getMessage()).build(); } catch (UserStoreException ex) { log.error(ex.getMessage(), ex); return Response.status(500).entity(ex.getMessage()).build(); @@ -206,7 +204,8 @@ public class RaspberryPiServiceImpl implements RaspberryPiService { } if (apiApplicationKey == null) { String applicationUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() - .getRealmConfiguration().getAdminUserName(); + .getRealmConfiguration().getAdminUserName() + "@" + PrivilegedCarbonContext + .getThreadLocalCarbonContext().getTenantDomain(); APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService(); String[] tags = {RaspberrypiConstants.DEVICE_TYPE}; apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys( diff --git a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/APIUtil.java b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/APIUtil.java index fee581528..07f9b702c 100644 --- a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/APIUtil.java +++ b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/APIUtil.java @@ -17,7 +17,6 @@ import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorization import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfigurationManagementService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.dto.SensorRecord; -import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService; import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; import java.util.ArrayList; @@ -170,18 +169,6 @@ public class APIUtil { return deviceAccessAuthorizationService; } - public static OutputEventAdapterService getOutputEventAdapterService() { - PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); - OutputEventAdapterService outputEventAdapterService = - (OutputEventAdapterService) ctx.getOSGiService(OutputEventAdapterService.class, null); - if (outputEventAdapterService == null) { - String msg = "Device Authorization service has not initialized."; - log.error(msg); - throw new IllegalStateException(msg); - } - return outputEventAdapterService; - } - public static PlatformConfigurationManagementService getTenantConfigurationManagementService() { PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); PlatformConfigurationManagementService tenantConfigurationManagementService = diff --git a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/ZipArchive.java b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/ZipArchive.java index eb5ed95da..2d955240e 100644 --- a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/ZipArchive.java +++ b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/ZipArchive.java @@ -18,23 +18,21 @@ package org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util; -import java.io.File; - /** * This is an utility class to hold zip files. */ public class ZipArchive { - private File zipFile = null; + private byte[] zipFileContent = null; private String fileName = null; - public ZipArchive(String fileName, File zipFile) { + public ZipArchive(String fileName, byte[] zipFile) { this.fileName = fileName; - this.zipFile = zipFile; + this.zipFileContent = zipFile; } - public File getZipFile() { - return zipFile; + public byte[] getZipFileContent() { + return zipFileContent; } public String getFileName() { diff --git a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/ZipUtil.java b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/ZipUtil.java index e902609de..bb2a92b85 100644 --- a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/ZipUtil.java +++ b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/ZipUtil.java @@ -18,27 +18,22 @@ package org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util; -import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.base.ServerConfiguration; import org.wso2.carbon.core.util.Utils; import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry; import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException; import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; import org.wso2.carbon.utils.CarbonUtils; -import org.wso2.carbon.utils.NetworkUtils; -import java.io.BufferedInputStream; import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.net.SocketException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -69,8 +64,6 @@ public class ZipUtil { String refreshToken) throws DeviceManagementException { String sketchFolder = "repository" + File.separator + "resources" + File.separator + "sketches"; - String archivesPath = CarbonUtils.getCarbonHome() + File.separator + sketchFolder + File.separator + "archives" + - File.separator + deviceId; String templateSketchPath = sketchFolder + File.separator + deviceType; String iotServerIP; @@ -117,7 +110,7 @@ public class ZipUtil { contextParams.put("DEVICE_REFRESH_TOKEN", refreshToken); ZipArchive zipFile; - zipFile = getSketchArchive(archivesPath, templateSketchPath, contextParams, deviceName); + zipFile = getSketchArchive(templateSketchPath, contextParams, deviceName); return zipFile; } catch (IOException e) { throw new DeviceManagementException("Zip File Creation Failed", e); @@ -126,7 +119,7 @@ public class ZipUtil { } } - public static String getServerUrl() { + private static String getServerUrl() { try { return org.apache.axis2.util.Utils.getIpAddress(); } catch (SocketException e) { @@ -135,32 +128,26 @@ public class ZipUtil { } } - private static ZipArchive getSketchArchive(String archivesPath, String templateSketchPath, Map contextParams + private ZipArchive getSketchArchive(String templateSketchPath, Map contextParams , String zipFileName) throws DeviceManagementException, IOException { String sketchPath = CarbonUtils.getCarbonHome() + File.separator + templateSketchPath; - FileUtils.deleteDirectory(new File(archivesPath));//clear directory - FileUtils.deleteDirectory(new File(archivesPath + ".zip"));//clear zip - if (!new File(archivesPath).mkdirs()) { //new dir - String message = "Could not create directory at path: " + archivesPath; - log.error(message); - throw new DeviceManagementException(message); - } zipFileName = zipFileName + ".zip"; try { Map> properties = getProperties(sketchPath + File.separator + "sketch" + ".properties"); List templateFiles = properties.get("templates"); + List processTemplateFiles = new ArrayList<>(); for (String templateFile : templateFiles) { - parseTemplate(templateSketchPath + File.separator + templateFile, archivesPath + File.separator + templateFile, - contextParams); + TemplateFile tFile = new TemplateFile(); + tFile.setContent(parseTemplate(templateSketchPath + File.separator + templateFile, contextParams)); + tFile.setFileName(templateFile); + processTemplateFiles.add(tFile); } templateFiles.add("sketch.properties"); // ommit copying the props file - copyFolder(new File(sketchPath), new File(archivesPath), templateFiles); - createZipArchive(archivesPath); - FileUtils.deleteDirectory(new File(archivesPath)); - File zip = new File(archivesPath + ".zip"); + + byte[] zip = createZipArchive(templateSketchPath, processTemplateFiles); return new ZipArchive(zipFileName, zip); } catch (IOException ex) { throw new DeviceManagementException( @@ -200,148 +187,124 @@ public class ZipUtil { } } - private static void parseTemplate(String srcFile, String dstFile, Map contextParams) throws IOException { + private static String parseTemplate(String srcFile, Map contextParams) throws IOException { //read from file FileInputStream inputStream = null; - FileOutputStream outputStream = null; try { inputStream = new FileInputStream(srcFile); - outputStream = new FileOutputStream(dstFile); String content = IOUtils.toString(inputStream, StandardCharsets.UTF_8.toString()); Iterator iterator = contextParams.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry mapEntry = (Map.Entry) iterator.next(); content = content.replaceAll("\\$\\{" + mapEntry.getKey() + "\\}", mapEntry.getValue().toString()); } - IOUtils.write(content, outputStream, StandardCharsets.UTF_8.toString()); + return content; } finally { if (inputStream != null) { inputStream.close(); } - if (outputStream != null) { - outputStream.close(); - } - } - } - - private static void copyFolder(File src, File dest, List excludeFileNames) throws IOException { - - if (src.isDirectory()) { - //if directory not exists, create it - if (!dest.exists() && !dest.mkdirs()) { - String message = "Could not create directory at path: " + dest; - log.error(message); - throw new IOException(message); - } - //list all the directory contents - String files[] = src.list(); - - if (files == null) { - log.warn("There are no files insides the directory " + src.getAbsolutePath()); - return; - } - - for (String file : files) { - //construct the src and dest file structure - File srcFile = new File(src, file); - File destFile = new File(dest, file); - //recursive copy - copyFolder(srcFile, destFile, excludeFileNames); - } - - } else { - for (String fileName : excludeFileNames) { - if (src.getName().equals(fileName)) { - return; - } - } - //if file, then copy it - //Use bytes stream to support all file types - InputStream in = null; - OutputStream out = null; - - try { - in = new FileInputStream(src); - out = new FileOutputStream(dest); - - byte[] buffer = new byte[1024]; - - int length; - //copy the file content in bytes - while ((length = in.read(buffer)) > 0) { - out.write(buffer, 0, length); - } - } finally { - if (in != null) { - in.close(); - } - if (out != null) { - out.close(); - } - } } } - private static boolean createZipArchive(String srcFolder) throws IOException { - BufferedInputStream origin = null; + private static byte[] createZipArchive(String srcFolder, List processTemplateFiles) throws IOException { ZipOutputStream out = null; - + ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { - final int BUFFER = 2048; - FileOutputStream dest = new FileOutputStream(new File(srcFolder + ".zip")); - out = new ZipOutputStream(new BufferedOutputStream(dest)); - byte data[] = new byte[BUFFER]; + out = new ZipOutputStream(new BufferedOutputStream(baos)); File subDir = new File(srcFolder); String subdirList[] = subDir.list(); if (subdirList == null) { log.warn("The sub directory " + subDir.getAbsolutePath() + " is empty"); - return false; + return null; } for (String sd : subdirList) { // get a list of files from current directory - File f = new File(srcFolder + "/" + sd); + File f = new File(srcFolder + File.separator + sd); if (f.isDirectory()) { String files[] = f.list(); if (files == null) { log.warn("The current directory " + f.getAbsolutePath() + " is empty. Has no files"); - return false; + return null; } for (int i = 0; i < files.length; i++) { - FileInputStream fi = new FileInputStream(srcFolder + "/" + sd + "/" + files[i]); - origin = new BufferedInputStream(fi, BUFFER); - ZipEntry entry = new ZipEntry(sd + "/" + files[i]); - out.putNextEntry(entry); - int count; - while ((count = origin.read(data, 0, BUFFER)) != -1) { - out.write(data, 0, count); - out.flush(); + boolean fileAdded = false; + for (TemplateFile templateFile : processTemplateFiles) { + if (files[i].equals(templateFile.getFileName())) { + ZipEntry entry = new ZipEntry(templateFile.getFileName()); + out.putNextEntry(entry); + out.write(templateFile.getContent().getBytes()); + out.closeEntry(); + fileAdded = true; + break; + } else if (f.getName().equals("sketch.properties")) { + fileAdded = true; + break; + } + } + if (fileAdded) { + continue; } + ZipEntry entry = new ZipEntry(sd + File.separator + files[i]); + out.putNextEntry(entry); + out.write(IOUtils.toByteArray(new FileInputStream(srcFolder + File.separator + sd + + File.separator + files[i]))); + out.closeEntry(); } } else //it is just a file { - FileInputStream fi = new FileInputStream(f); - origin = new BufferedInputStream(fi, BUFFER); + boolean fileAdded = false; + for (TemplateFile templateFile : processTemplateFiles) { + if (f.getName().equals(templateFile.getFileName())) { + ZipEntry entry = new ZipEntry(templateFile.getFileName()); + out.putNextEntry(entry); + out.write(templateFile.getContent().getBytes()); + out.closeEntry(); + fileAdded = true; + break; + } else if (f.getName().equals("sketch.properties")) { + fileAdded = true; + break; + } + } + if (fileAdded) { + continue; + } ZipEntry entry = new ZipEntry(sd); out.putNextEntry(entry); - int count; - while ((count = origin.read(data, 0, BUFFER)) != -1) { - out.write(data, 0, count); - out.flush(); - } + out.write(IOUtils.toByteArray(new FileInputStream(f))); + out.closeEntry(); } } - out.flush(); + out.finish(); } finally { - if (origin != null) { - origin.close(); - } if (out != null) { out.close(); } } - return true; + return baos.toByteArray(); + } + + public class TemplateFile { + private String content; + private String fileName; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } } } diff --git a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/pom.xml b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/pom.xml index 8c832bbf3..d0d8f6d8d 100644 --- a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/pom.xml +++ b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/pom.xml @@ -23,7 +23,7 @@ raspberrypi-plugin org.wso2.carbon.devicemgt-plugins - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.type-view/public/js/download.js b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.type-view/public/js/download.js index f6b9f1e64..abd0a49f5 100644 --- a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.type-view/public/js/download.js +++ b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.type-view/public/js/download.js @@ -21,6 +21,8 @@ var modalPopupContainer = modalPopup + " .modal-content"; var modalPopupContent = modalPopup + " .modal-content"; var body = "body"; +var backendEndBasePath = "/api/device-mgt/v1.0"; + /* * set popup maximum height function. */ @@ -180,4 +182,31 @@ function doAction(data) { hidePopup(); }); } +} + +function artifactUpload() { + var contentType = "application/json"; + + var urix = backendEndBasePath + "/admin/devicetype/deploy/raspberrypi"; + var defaultStatusClasses = "fw fw-stack-1x"; + var content = $("#raspberrypi-statistic-response-template").find(".content"); + var title = content.find("#title"); + var statusIcon = content.find("#status-icon"); + var data = {} + invokerUtil.post(urix, data, function (data) { + title.html("Deploying statistic artifacts. Please wait..."); + statusIcon.attr("class", defaultStatusClasses + " fw-check"); + $(modalPopupContent).html(content.html()); + showPopup(); + setTimeout(function () { + hidePopup(); + location.reload(true); + }, 5000); + + }, function (jqXHR) { + title.html("Failed to deploy artifacts, Please contact administrator."); + statusIcon.attr("class", defaultStatusClasses + " fw-error"); + $(modalPopupContent).html(content.html()); + showPopup(); + }, contentType); } \ No newline at end of file diff --git a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.type-view/type-view.hbs b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.type-view/type-view.hbs index 8b645b36a..000e232a4 100644 --- a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.type-view/type-view.hbs +++ b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.type-view/type-view.hbs @@ -61,6 +61,10 @@ Download Agent + {{#if displayStatus}} + Deploy Analytics Artifacts + {{/if}} + @@ -275,6 +279,27 @@ + + {{#zone "topCss"}} {{css "css/styles.css"}} {{/zone}} diff --git a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.type-view/type-view.js b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.type-view/type-view.js new file mode 100644 index 000000000..ef40e6ebe --- /dev/null +++ b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.type-view/type-view.js @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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. + */ + +function onRequest(context){ + var viewModel = {}; + var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"]; + var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"]; + var url = devicemgtProps["httpsURL"] + "/api/device-mgt/v1.0/admin/devicetype/deploy/raspberrypi/status"; + serviceInvokers.XMLHttp.get( + url, function (responsePayload) { + var responseContent = responsePayload.status; + new Log().error(responseContent); + if ("204" == responsePayload.status) { + viewModel["displayStatus"] = "Display"; + } + }, + function (responsePayload) { + //do nothing. + } + ); + return viewModel; +} \ No newline at end of file diff --git a/components/device-types/raspberrypi-plugin/pom.xml b/components/device-types/raspberrypi-plugin/pom.xml index 15fec876b..df73d46e8 100644 --- a/components/device-types/raspberrypi-plugin/pom.xml +++ b/components/device-types/raspberrypi-plugin/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.devicemgt-plugins device-types - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.impl/pom.xml b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.impl/pom.xml index d739f8d11..c734bcc8c 100644 --- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.impl/pom.xml +++ b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.impl/pom.xml @@ -23,7 +23,7 @@ virtual-fire-alarm-plugin org.wso2.carbon.devicemgt-plugins - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/pom.xml b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/pom.xml index ec91a2e5d..890d96bd3 100644 --- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/pom.xml +++ b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/pom.xml @@ -23,7 +23,7 @@ virtual-fire-alarm-plugin org.wso2.carbon.devicemgt-plugins - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.analytics/pom.xml b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.analytics/pom.xml index 436d77892..0d2033256 100644 --- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.analytics/pom.xml +++ b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.analytics/pom.xml @@ -21,7 +21,7 @@ virtual-fire-alarm-plugin org.wso2.carbon.devicemgt-plugins - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.analytics/src/main/resources/carbonapps/virtualfirealarm/virtualfirealarm_receiver/virtualfirealarm_receiver.xml b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.analytics/src/main/resources/carbonapps/virtualfirealarm/virtualfirealarm_receiver/virtualfirealarm_receiver.xml index 7f7b3cf7f..d46fc1a56 100644 --- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.analytics/src/main/resources/carbonapps/virtualfirealarm/virtualfirealarm_receiver/virtualfirealarm_receiver.xml +++ b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.analytics/src/main/resources/carbonapps/virtualfirealarm/virtualfirealarm_receiver/virtualfirealarm_receiver.xml @@ -18,10 +18,8 @@ --> - carbon.super/virtual_firealarm/+/temperature - admin - admin - org.wso2.carbon.device.mgt.input.adapter.mqtt.util.MQTTContentValidator + ${tenant-domain}/virtual_firealarm/+/temperature + iot-mqtt true diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/pom.xml b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/pom.xml index 024ef6b57..f9de24275 100644 --- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/pom.xml +++ b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/pom.xml @@ -21,7 +21,7 @@ virtual-fire-alarm-plugin org.wso2.carbon.devicemgt-plugins - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml @@ -51,18 +51,6 @@ - - org.wso2.carbon.devicemgt - org.wso2.carbon.device.mgt.analytics.data.publisher - provided - - - org.apache.axis2.wso2 - axis2-client - - - - org.wso2.carbon.devicemgt org.wso2.carbon.certificate.mgt.core diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmService.java b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmService.java index 6585280f0..2726948d2 100644 --- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmService.java +++ b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmService.java @@ -45,7 +45,7 @@ import javax.ws.rs.core.Response; } ), tags = { - @Tag(name = "virtual_firealarm", description = "") + @Tag(name = "virtual_firealarm,device_management", description = "") } ) @Scopes( diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmServiceImpl.java b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmServiceImpl.java index f5bb1d84b..faec317e0 100644 --- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmServiceImpl.java +++ b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmServiceImpl.java @@ -58,15 +58,11 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; -import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; -import java.security.PrivateKey; import java.util.ArrayList; import java.util.Date; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Properties; import java.util.UUID; @@ -134,40 +130,6 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService { } } - @PUT - @Path("device/{deviceId}/policy") - public Response updatePolicy(@PathParam("deviceId") String deviceId, @QueryParam("protocol") String protocol, - @FormParam("policy") String policy) { - String protocolString = protocol.toUpperCase(); - if (log.isDebugEnabled()) { - log.debug("Sending request to update-policy of device [" + deviceId + "] via " + protocolString); - } - try { - if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized( - new DeviceIdentifier(deviceId, VirtualFireAlarmConstants.DEVICE_TYPE), - DeviceGroupConstants.Permissions.DEFAULT_MANAGE_POLICIES_PERMISSIONS)) { - return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); - } - String actualMessage = VirtualFireAlarmConstants.POLICY_CONTEXT + ":" + policy; - Map dynamicProperties = new HashMap<>(); - String publishTopic = APIUtil.getTenantDomainOftheUser() + "/" - + VirtualFireAlarmConstants.DEVICE_TYPE + "/" + deviceId; - dynamicProperties.put(VirtualFireAlarmConstants.ADAPTER_TOPIC_PROPERTY, publishTopic); - dynamicProperties.put(VirtualFireAlarmConstants.JID_PROPERTY_KEY, - deviceId + "@" + XmppConfig.getInstance().getServerName()); - dynamicProperties.put(VirtualFireAlarmConstants.SUBJECT_PROPERTY_KEY, "POLICTY-REQUEST"); - dynamicProperties.put(VirtualFireAlarmConstants.MESSAGE_TYPE_PROPERTY_KEY, - VirtualFireAlarmConstants.CHAT_PROPERTY_KEY); - APIUtil.getOutputEventAdapterService().publish(VirtualFireAlarmConstants.XMPP_ADAPTER_NAME, - dynamicProperties, actualMessage); - return Response.ok().build(); - } catch (DeviceAccessAuthorizationException e) { - log.error(e.getErrorMessage(), e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); - } - } - - @Path("device/stats/{deviceId}") @GET @Consumes("application/json") @@ -206,13 +168,14 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService { public Response downloadSketch(@QueryParam("deviceName") String deviceName, @QueryParam("sketchType") String sketchType) { try { - ZipArchive zipFile = createDownloadFile(APIUtil.getAuthenticatedUser(), deviceName, sketchType); - Response.ResponseBuilder response = Response.ok(FileUtils.readFileToByteArray(zipFile.getZipFile())); + String user = APIUtil.getAuthenticatedUser() + "@" + PrivilegedCarbonContext.getThreadLocalCarbonContext() + .getTenantDomain(); + ZipArchive zipFile = createDownloadFile(user, deviceName, sketchType); + Response.ResponseBuilder response = Response.ok(zipFile.getZipFileContent()); response.status(Response.Status.OK); response.type("application/zip"); response.header("Content-Disposition", "attachment; filename=\"" + zipFile.getFileName() + "\""); Response resp = response.build(); - zipFile.getZipFile().delete(); return resp; } catch (IllegalArgumentException ex) { return Response.status(400).entity(ex.getMessage()).build();//bad request @@ -225,9 +188,6 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService { } catch (APIManagerException ex) { log.error(ex.getMessage(), ex); return Response.status(500).entity(ex.getMessage()).build(); - } catch (IOException ex) { - log.error(ex.getMessage(), ex); - return Response.status(500).entity(ex.getMessage()).build(); } catch (UserStoreException ex) { log.error(ex.getMessage(), ex); return Response.status(500).entity(ex.getMessage()).build(); @@ -276,7 +236,8 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService { if (apiApplicationKey == null) { String applicationUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm().getRealmConfiguration() - .getAdminUserName(); + .getAdminUserName() + "@" + PrivilegedCarbonContext.getThreadLocalCarbonContext() + .getTenantDomain(); APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService(); String[] tags = {VirtualFireAlarmConstants.DEVICE_TYPE}; apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys( diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/APIUtil.java b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/APIUtil.java index d302e7281..bbcf1acef 100644 --- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/APIUtil.java +++ b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/APIUtil.java @@ -16,7 +16,6 @@ import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorization import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfigurationManagementService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.SensorRecord; -import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService; import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; import java.util.ArrayList; @@ -169,18 +168,6 @@ public class APIUtil { return deviceAccessAuthorizationService; } - public static OutputEventAdapterService getOutputEventAdapterService() { - PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); - OutputEventAdapterService outputEventAdapterService = - (OutputEventAdapterService) ctx.getOSGiService(OutputEventAdapterService.class, null); - if (outputEventAdapterService == null) { - String msg = "Device Authorization service has not initialized."; - log.error(msg); - throw new IllegalStateException(msg); - } - return outputEventAdapterService; - } - public static PlatformConfigurationManagementService getTenantConfigurationManagementService() { PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); PlatformConfigurationManagementService tenantConfigurationManagementService = diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipArchive.java b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipArchive.java index 22fda92b3..2152a5e36 100644 --- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipArchive.java +++ b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipArchive.java @@ -18,23 +18,23 @@ package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util; -import java.io.File; +import java.util.zip.ZipOutputStream; /** * This is an utility class to hold zip files. */ public class ZipArchive { - private File zipFile = null; + private byte[] zipFileContent = null; private String fileName = null; - public ZipArchive(String fileName, File zipFile) { + public ZipArchive(String fileName, byte[] zipFile) { this.fileName = fileName; - this.zipFile = zipFile; + this.zipFileContent = zipFile; } - public File getZipFile() { - return zipFile; + public byte[] getZipFileContent() { + return zipFileContent; } public String getFileName() { diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipUtil.java b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipUtil.java index e9bcb6c60..496d5eb5a 100644 --- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipUtil.java +++ b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipUtil.java @@ -19,7 +19,6 @@ package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util; import org.apache.commons.codec.binary.Base64; -import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -33,14 +32,12 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.xmpp.XmppConfig; import org.wso2.carbon.utils.CarbonUtils; -import java.io.BufferedInputStream; import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.net.SocketException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -59,24 +56,18 @@ import java.util.zip.ZipOutputStream; public class ZipUtil { private static final Log log = LogFactory.getLog(ZipUtil.class); - private static final String HTTPS_PORT_PROPERTY = "httpsPort"; - private static final String HTTP_PORT_PROPERTY = "httpPort"; private static final String LOCALHOST = "localhost"; private static final String HTTPS_PROTOCOL_URL = "https://${iot.gateway.host}:${iot.gateway.https.port}"; private static final String HTTP_PROTOCOL_URL = "http://${iot.gateway.host}:${iot.gateway.http.port}"; private static final String CONFIG_TYPE = "general"; private static final String DEFAULT_MQTT_ENDPOINT = "tcp://${mqtt.broker.host}:${mqtt.broker.port}"; - public static final String HOST_NAME = "HostName"; public ZipArchive createZipFile(String owner, String deviceType, String deviceId, String deviceName, String apiApplicationKey, String token, String refreshToken) throws DeviceManagementException { String sketchFolder = "repository" + File.separator + "resources" + File.separator + "sketches"; - String archivesPath = - CarbonUtils.getCarbonHome() + File.separator + sketchFolder + File.separator + "archives" + - File.separator + deviceId; String templateSketchPath = sketchFolder + File.separator + deviceType; String iotServerIP; @@ -141,7 +132,7 @@ public class ZipUtil { ? "" : XmppConfig.getInstance().getJid()); ZipArchive zipFile; - zipFile = getSketchArchive(archivesPath, templateSketchPath, contextParams, deviceName); + zipFile = getSketchArchive(templateSketchPath, contextParams, deviceName); return zipFile; } catch (IOException e) { throw new DeviceManagementException("Zip File Creation Failed", e); @@ -159,7 +150,7 @@ public class ZipUtil { return Base64.encodeBase64String(stringToEncode.getBytes()); } - public static String getServerUrl() { + private static String getServerUrl() { try { return org.apache.axis2.util.Utils.getIpAddress(); } catch (SocketException e) { @@ -168,33 +159,27 @@ public class ZipUtil { } } - public static ZipArchive getSketchArchive(String archivesPath, String templateSketchPath, Map contextParams + private ZipArchive getSketchArchive(String templateSketchPath, Map contextParams , String zipFileName) throws DeviceManagementException, IOException { String sketchPath = CarbonUtils.getCarbonHome() + File.separator + templateSketchPath; - FileUtils.deleteDirectory(new File(archivesPath));//clear directory - FileUtils.deleteDirectory(new File(archivesPath + ".zip"));//clear zip - if (!new File(archivesPath).mkdirs()) { //new dir - String message = "Could not create directory at path: " + archivesPath; - log.error(message); - throw new DeviceManagementException(message); - } zipFileName = zipFileName + ".zip"; try { Map> properties = getProperties(sketchPath + File.separator + "sketch" + ".properties"); List templateFiles = properties.get("templates"); + List processTemplateFiles = new ArrayList<>(); for (String templateFile : templateFiles) { - parseTemplate(templateSketchPath + File.separator + templateFile, archivesPath + File.separator + templateFile, - contextParams); + TemplateFile tFile = new TemplateFile(); + tFile.setContent(parseTemplate(templateSketchPath + File.separator + templateFile, contextParams)); + tFile.setFileName(templateFile); + processTemplateFiles.add(tFile); } templateFiles.add("sketch.properties"); // ommit copying the props file - copyFolder(new File(sketchPath), new File(archivesPath), templateFiles); - createZipArchive(archivesPath); - FileUtils.deleteDirectory(new File(archivesPath)); - File zip = new File(archivesPath + ".zip"); - return new org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.ZipArchive(zipFileName, zip); + + byte[] zip = createZipArchive(templateSketchPath, processTemplateFiles); + return new ZipArchive(zipFileName, zip); } catch (IOException ex) { throw new DeviceManagementException( "Error occurred when trying to read property " + "file sketch.properties", ex); @@ -206,9 +191,7 @@ public class ZipUtil { InputStream input = null; try { - input = new FileInputStream(propertyFilePath); - // load a properties file prop.load(input); Map> properties = new HashMap>(); @@ -235,148 +218,124 @@ public class ZipUtil { } } - private static void parseTemplate(String srcFile, String dstFile, Map contextParams) throws IOException { + private static String parseTemplate(String srcFile, Map contextParams) throws IOException { //read from file FileInputStream inputStream = null; - FileOutputStream outputStream = null; try { inputStream = new FileInputStream(srcFile); - outputStream = new FileOutputStream(dstFile); String content = IOUtils.toString(inputStream, StandardCharsets.UTF_8.toString()); Iterator iterator = contextParams.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry mapEntry = (Map.Entry) iterator.next(); content = content.replaceAll("\\$\\{" + mapEntry.getKey() + "\\}", mapEntry.getValue().toString()); } - IOUtils.write(content, outputStream, StandardCharsets.UTF_8.toString()); + return content; } finally { if (inputStream != null) { inputStream.close(); } - if (outputStream != null) { - outputStream.close(); - } } } - private static void copyFolder(File src, File dest, List excludeFileNames) throws IOException { - - if (src.isDirectory()) { - //if directory not exists, create it - if (!dest.exists() && !dest.mkdirs()) { - String message = "Could not create directory at path: " + dest; - log.error(message); - throw new IOException(message); - } - //list all the directory contents - String files[] = src.list(); - - if (files == null) { - log.warn("There are no files insides the directory " + src.getAbsolutePath()); - return; - } - - for (String file : files) { - //construct the src and dest file structure - File srcFile = new File(src, file); - File destFile = new File(dest, file); - //recursive copy - copyFolder(srcFile, destFile, excludeFileNames); - } - - } else { - for (String fileName : excludeFileNames) { - if (src.getName().equals(fileName)) { - return; - } - } - //if file, then copy it - //Use bytes stream to support all file types - InputStream in = null; - OutputStream out = null; - - try { - in = new FileInputStream(src); - out = new FileOutputStream(dest); - - byte[] buffer = new byte[1024]; - - int length; - //copy the file content in bytes - while ((length = in.read(buffer)) > 0) { - out.write(buffer, 0, length); - } - } finally { - if (in != null) { - in.close(); - } - if (out != null) { - out.close(); - } - } - } - } - - private static boolean createZipArchive(String srcFolder) throws IOException { - BufferedInputStream origin = null; + private static byte[] createZipArchive(String srcFolder, List processTemplateFiles) throws IOException { ZipOutputStream out = null; - + ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { - final int BUFFER = 2048; - FileOutputStream dest = new FileOutputStream(new File(srcFolder + ".zip")); - out = new ZipOutputStream(new BufferedOutputStream(dest)); - byte data[] = new byte[BUFFER]; + out = new ZipOutputStream(new BufferedOutputStream(baos)); File subDir = new File(srcFolder); String subdirList[] = subDir.list(); if (subdirList == null) { log.warn("The sub directory " + subDir.getAbsolutePath() + " is empty"); - return false; + return null; } for (String sd : subdirList) { // get a list of files from current directory - File f = new File(srcFolder + "/" + sd); + File f = new File(srcFolder + File.separator + sd); if (f.isDirectory()) { String files[] = f.list(); if (files == null) { log.warn("The current directory " + f.getAbsolutePath() + " is empty. Has no files"); - return false; + return null; } for (int i = 0; i < files.length; i++) { - FileInputStream fi = new FileInputStream(srcFolder + "/" + sd + "/" + files[i]); - origin = new BufferedInputStream(fi, BUFFER); - ZipEntry entry = new ZipEntry(sd + "/" + files[i]); - out.putNextEntry(entry); - int count; - while ((count = origin.read(data, 0, BUFFER)) != -1) { - out.write(data, 0, count); - out.flush(); + boolean fileAdded = false; + for (TemplateFile templateFile : processTemplateFiles) { + if (files[i].equals(templateFile.getFileName())) { + ZipEntry entry = new ZipEntry(templateFile.getFileName()); + out.putNextEntry(entry); + out.write(templateFile.getContent().getBytes()); + out.closeEntry(); + fileAdded = true; + break; + } else if (f.getName().equals("sketch.properties")) { + fileAdded = true; + break; + } } + if (fileAdded) { + continue; + } + ZipEntry entry = new ZipEntry(sd + File.separator + files[i]); + out.putNextEntry(entry); + out.write(IOUtils.toByteArray(new FileInputStream(srcFolder + File.separator + sd + + File.separator + files[i]))); + out.closeEntry(); } } else //it is just a file { - FileInputStream fi = new FileInputStream(f); - origin = new BufferedInputStream(fi, BUFFER); + boolean fileAdded = false; + for (TemplateFile templateFile : processTemplateFiles) { + if (f.getName().equals(templateFile.getFileName())) { + ZipEntry entry = new ZipEntry(templateFile.getFileName()); + out.putNextEntry(entry); + out.write(templateFile.getContent().getBytes()); + out.closeEntry(); + fileAdded = true; + break; + } else if (f.getName().equals("sketch.properties")) { + fileAdded = true; + break; + } + } + if (fileAdded) { + continue; + } ZipEntry entry = new ZipEntry(sd); out.putNextEntry(entry); - int count; - while ((count = origin.read(data, 0, BUFFER)) != -1) { - out.write(data, 0, count); - out.flush(); - } + out.write(IOUtils.toByteArray(new FileInputStream(f))); + out.closeEntry(); } } - out.flush(); + out.finish(); } finally { - if (origin != null) { - origin.close(); - } if (out != null) { out.close(); } } - return true; + return baos.toByteArray(); + } + + public class TemplateFile { + private String content; + private String fileName; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } } } diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/util/Utils.java b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/util/Utils.java deleted file mode 100644 index 586de223c..000000000 --- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/util/Utils.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. 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.iot.virtualfirealarm.service.impl.util.util; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.base.ServerConfiguration; -import org.wso2.carbon.device.mgt.common.DeviceManagementException; -import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.ZipArchive; -import org.wso2.carbon.utils.CarbonUtils; -import org.wso2.carbon.utils.NetworkUtils; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.SocketException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -/** - * Provides utility methods required by the device type plugins. - */ -public class Utils { - - public static final String HOST_NAME = "HostName"; - private static final Log log = LogFactory.getLog(Utils.class); - - - -} diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.scep.api/pom.xml b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.scep.api/pom.xml deleted file mode 100644 index ea477f5eb..000000000 --- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.scep.api/pom.xml +++ /dev/null @@ -1,199 +0,0 @@ - - - - - - virtual-fire-alarm-plugin - org.wso2.carbon.devicemgt-plugins - 3.0.6-SNAPSHOT - ../pom.xml - - - 4.0.0 - org.wso2.carbon.device.mgt.iot.virtualfirealarm.scep.api - war - WSO2 Carbon - IoT Server SCEP Server API - WSO2 Carbon - Virtual FireAlarm SCEP Server API Implementation - http://wso2.org - - - - - org.wso2.carbon.devicemgt - org.wso2.carbon.device.mgt.common - provided - - - org.wso2.carbon.devicemgt - org.wso2.carbon.device.mgt.core - provided - - - org.apache.axis2.wso2 - axis2-client - - - - - - org.wso2.carbon.devicemgt - org.wso2.carbon.certificate.mgt.core - provided - - - commons-codec - commons-codec - - - - - - - - org.apache.cxf - cxf-rt-frontend-jaxws - provided - - - org.apache.cxf - cxf-rt-frontend-jaxrs - provided - - - org.apache.cxf - cxf-rt-transports-http - provided - - - - - org.codehaus.jackson - jackson-core-asl - - - org.codehaus.jackson - jackson-jaxrs - - - javax - javaee-web-api - provided - - - javax.ws.rs - jsr311-api - provided - - - commons-httpclient.wso2 - commons-httpclient - provided - - - - org.wso2.carbon - org.wso2.carbon.utils - provided - - - org.bouncycastle.wso2 - bcprov-jdk15on - - - org.wso2.carbon - org.wso2.carbon.user.api - - - org.wso2.carbon - org.wso2.carbon.queuing - - - org.wso2.carbon - org.wso2.carbon.base - - - org.apache.axis2.wso2 - axis2 - - - org.igniterealtime.smack.wso2 - smack - - - org.igniterealtime.smack.wso2 - smackx - - - jaxen - jaxen - - - commons-fileupload.wso2 - commons-fileupload - - - org.apache.ant.wso2 - ant - - - org.apache.ant.wso2 - ant - - - commons-httpclient.wso2 - commons-httpclient - - - org.eclipse.equinox - javax.servlet - - - org.wso2.carbon - org.wso2.carbon.registry.api - - - - - - commons-codec - commons-codec - - - - - - - - maven-compiler-plugin - - UTF-8 - ${wso2.maven.compiler.source} - ${wso2.maven.compiler.target} - - - - maven-war-plugin - - virtual_firealarm_scep - - - - - - diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/pom.xml b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/pom.xml index 7fbe10a02..be4b79b20 100644 --- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/pom.xml +++ b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/pom.xml @@ -23,7 +23,7 @@ virtual-fire-alarm-plugin org.wso2.carbon.devicemgt-plugins - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.realtime.analytics-view/analytics-view.js b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.realtime.analytics-view/analytics-view.js index 7aaad19c6..5c34b9331 100644 --- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.realtime.analytics-view/analytics-view.js +++ b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.realtime.analytics-view/analytics-view.js @@ -39,4 +39,4 @@ function onRequest(context) { + "deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type + "&websocketToken=" + token; } return {"device": device, "websocketEndpoint": websocketEndpoint}; -} \ No newline at end of file +} diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.type-view/public/js/download.js b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.type-view/public/js/download.js index 991796825..a667ef4cc 100644 --- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.type-view/public/js/download.js +++ b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.type-view/public/js/download.js @@ -21,6 +21,8 @@ var modalPopupContainer = modalPopup + " .modal-content"; var modalPopupContent = modalPopup + " .modal-content"; var body = "body"; +var backendEndBasePath = "/api/device-mgt/v1.0"; + /* * Set popup maximum height function. */ @@ -132,4 +134,31 @@ function doAction(data) { hideAgentDownloadPopup(); }); } +} + +function artifactUpload() { + var contentType = "application/json"; + + var urix = backendEndBasePath + "/admin/devicetype/deploy/virtual_firealarm"; + var defaultStatusClasses = "fw fw-stack-1x"; + var content = $("#virtualfirealarm-statistic-response-template").find(".content"); + var title = content.find("#title"); + var statusIcon = content.find("#status-icon"); + var data = {} + invokerUtil.post(urix, data, function (data) { + title.html("Deploying statistic artifacts. Please wait..."); + statusIcon.attr("class", defaultStatusClasses + " fw-check"); + $(modalPopupContent).html(content.html()); + showPopup(); + setTimeout(function () { + hidePopup(); + location.reload(true); + }, 5000); + + }, function (jqXHR) { + title.html("Failed to deploy artifacts, Please contact administrator."); + statusIcon.attr("class", defaultStatusClasses + " fw-error"); + $(modalPopupContent).html(content.html()); + showPopup(); + }, contentType); } \ No newline at end of file diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.type-view/type-view.hbs b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.type-view/type-view.hbs index c37a9b9c0..922ace659 100644 --- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.type-view/type-view.hbs +++ b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.type-view/type-view.hbs @@ -54,6 +54,10 @@ Download Agent + {{#if displayStatus}} + Deploy Analytics Artifacts + {{/if}} + @@ -260,6 +264,27 @@ + + {{#zone "topCss"}} {{css "css/styles.css"}} {{/zone}} diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.type-view/type-view.js b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.type-view/type-view.js new file mode 100644 index 000000000..ea24f499c --- /dev/null +++ b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.type-view/type-view.js @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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. + */ + +function onRequest(context){ + var viewModel = {}; + var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"]; + var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"]; + var url = devicemgtProps["httpsURL"] + "/api/device-mgt/v1.0/admin/devicetype/deploy/virtual_firealarm/status"; + serviceInvokers.XMLHttp.get( + url, function (responsePayload) { + var responseContent = responsePayload.status; + new Log().error(responseContent); + if ("204" == responsePayload.status) { + viewModel["displayStatus"] = "Display"; + } + }, + function (responsePayload) { + //do nothing. + } + ); + return viewModel; +} \ No newline at end of file diff --git a/components/device-types/virtual-fire-alarm-plugin/pom.xml b/components/device-types/virtual-fire-alarm-plugin/pom.xml index 935d73e49..f55d5fb32 100644 --- a/components/device-types/virtual-fire-alarm-plugin/pom.xml +++ b/components/device-types/virtual-fire-alarm-plugin/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.devicemgt-plugins device-types - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.osgiconnector/pom.xml b/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.osgiconnector/pom.xml index f81aedf64..749323340 100644 --- a/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.osgiconnector/pom.xml +++ b/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.osgiconnector/pom.xml @@ -18,7 +18,7 @@ org.wso2.carbon.devicemgt-plugins appm-connector - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/pom.xml b/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/pom.xml index 95489a87c..34d79be58 100644 --- a/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/pom.xml +++ b/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/pom.xml @@ -18,7 +18,7 @@ org.wso2.carbon.devicemgt-plugins appm-connector - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml @@ -27,6 +27,7 @@ bundle WSO2 Carbon - App Manager WSO2 MDM REST Connector Component http://maven.apache.org + @@ -51,6 +52,8 @@ ${project.artifactId} org.wso2.carbon.appmgt.mdm.restconnector.internal + org.osgi.framework, + org.osgi.service.component, org.wso2.carbon.appmgt.mobile.utils.*, org.wso2.carbon.appmgt.mobile.mdm.*, org.wso2.carbon.appmgt.mobile.interfaces.*, @@ -62,7 +65,11 @@ feign.auth, feign.codec, feign.gson, - *;resolution:=optional + org.json.simple.*, + org.wso2.carbon.appmgt.mobile.beans, + org.wso2.carbon.context, + javax.net.ssl, + feign.slf4j !org.wso2.carbon.appmgt.mdm.restconnector.internal, @@ -70,8 +77,7 @@ jsr311-api, - feign-jaxrs, - org.wso2.carbon.device.mgt.common + feign-jaxrs @@ -80,38 +86,14 @@ - - commons-io.wso2 - commons-io - com.googlecode.json-simple.wso2 json-simple - - com.googlecode.plist - dd-plist - org.wso2.carbon org.wso2.carbon.logging - - org.apache.felix - org.apache.felix.scr - - - org.wso2.carbon - org.wso2.carbon.ndatasource.core - - - org.wso2.carbon.governance - org.wso2.carbon.governance.api - - - org.wso2.carbon.appmgt - org.wso2.carbon.appmgt.mobile - org.wso2.carbon.devicemgt org.wso2.carbon.identity.jwt.client.extension @@ -136,21 +118,14 @@ io.swagger swagger-jaxrs - - org.wso2.carbon.devicemgt - org.wso2.carbon.device.mgt.common - - - org.apache.ws.commons.axiom - axiom-api - - - org.apache.ws.commons.axiom - axiom-impl - - - - + + org.wso2.carbon.appmgt + org.wso2.carbon.appmgt.mobile + + + io.github.openfeign + feign-slf4j + diff --git a/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/ApplicationOperationsImpl.java b/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/ApplicationOperationsImpl.java index 4f3580165..a049c3fab 100644 --- a/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/ApplicationOperationsImpl.java +++ b/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/ApplicationOperationsImpl.java @@ -17,16 +17,22 @@ */ package org.wso2.carbon.appmgt.mdm.restconnector; +import feign.Client; import feign.Feign; +import feign.Logger; +import feign.Request; +import feign.Response; import feign.gson.GsonDecoder; import feign.gson.GsonEncoder; import feign.jaxrs.JAXRSContract; +import feign.slf4j.Slf4jLogger; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.OAuthRequestInterceptor; +import org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto.Activity; import org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto.ApplicationManagementAdminService; import org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto.ApplicationWrapper; import org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto.DeviceManagementAdminService; @@ -42,8 +48,16 @@ import org.wso2.carbon.appmgt.mobile.mdm.Device; import org.wso2.carbon.appmgt.mobile.utils.MobileApplicationException; import org.wso2.carbon.appmgt.mobile.utils.MobileConfigurations; import org.wso2.carbon.context.PrivilegedCarbonContext; -import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -62,13 +76,13 @@ public class ApplicationOperationsImpl implements ApplicationOperations { public ApplicationOperationsImpl() { String authorizationConfigManagerServerURL = AuthorizationConfigurationManager.getInstance().getServerURL(); OAuthRequestInterceptor oAuthRequestInterceptor = new OAuthRequestInterceptor(); - deviceManagementAdminService = Feign.builder() - .requestInterceptor(oAuthRequestInterceptor) + deviceManagementAdminService = Feign.builder().client(getSSLClient()).logger(new Slf4jLogger()).logLevel( + Logger.Level.FULL).requestInterceptor(oAuthRequestInterceptor) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .target(DeviceManagementAdminService.class, authorizationConfigManagerServerURL + CDMF_SERVER_BASE_CONTEXT); - applicationManagementAdminService = Feign.builder() - .requestInterceptor(oAuthRequestInterceptor) + applicationManagementAdminService = Feign.builder().client(getSSLClient()).logger(new Slf4jLogger()).logLevel( + Logger.Level.FULL).requestInterceptor(oAuthRequestInterceptor) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .target(ApplicationManagementAdminService.class, authorizationConfigManagerServerURL + CDMF_SERVER_BASE_CONTEXT); @@ -271,4 +285,37 @@ public class ApplicationOperationsImpl implements ApplicationOperations { log.error(errorMessage); } } + + private static Client getSSLClient() { + return new Client.Default(getTrustedSSLSocketFactory(), new HostnameVerifier() { + @Override + public boolean verify(String s, SSLSession sslSession) { + return true; + } + }); + } + + private static SSLSocketFactory getTrustedSSLSocketFactory() { + try { + TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + public void checkClientTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + public void checkServerTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + } + }; + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, trustAllCerts, new java.security.SecureRandom()); + return sc.getSocketFactory(); + } catch (KeyManagementException | NoSuchAlgorithmException e) { + return null; + } + } + } \ No newline at end of file diff --git a/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/OAuthRequestInterceptor.java b/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/OAuthRequestInterceptor.java index 48bf79df8..9c4f80b71 100755 --- a/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/OAuthRequestInterceptor.java +++ b/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/OAuthRequestInterceptor.java @@ -17,13 +17,20 @@ */ package org.wso2.carbon.appmgt.mdm.restconnector.authorization.client; +import feign.Client; import feign.Feign; +import feign.Logger; +import feign.Request; import feign.RequestInterceptor; import feign.RequestTemplate; +import feign.Response; import feign.auth.BasicAuthRequestInterceptor; import feign.gson.GsonDecoder; import feign.gson.GsonEncoder; import feign.jaxrs.JAXRSContract; +import feign.slf4j.Slf4jLogger; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.wso2.carbon.appmgt.mdm.restconnector.Constants; import org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto.AccessTokenInfo; import org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto.ApiApplicationKey; @@ -33,6 +40,16 @@ import org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto.TokenIs import org.wso2.carbon.appmgt.mdm.restconnector.config.AuthorizationConfigurationManager; import org.wso2.carbon.appmgt.mdm.restconnector.internal.AuthorizationDataHolder; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; + /** * This is a request interceptor to add oauth token header. */ @@ -46,6 +63,8 @@ public class OAuthRequestInterceptor implements RequestInterceptor { private static final String REFRESH_GRANT_TYPE = "refresh_token"; private ApiApplicationRegistrationService apiApplicationRegistrationService; private TokenIssuerService tokenIssuerService; + private static Log log = LogFactory.getLog(OAuthRequestInterceptor.class); + /** * Creates an interceptor that authenticates all requests. @@ -54,8 +73,8 @@ public class OAuthRequestInterceptor implements RequestInterceptor { refreshTimeOffset = AuthorizationConfigurationManager.getInstance().getTokenRefreshTimeOffset(); String username = AuthorizationConfigurationManager.getInstance().getUserName(); String password = AuthorizationConfigurationManager.getInstance().getPassword(); - apiApplicationRegistrationService = Feign.builder().requestInterceptor( - new BasicAuthRequestInterceptor(username, password)) + apiApplicationRegistrationService = Feign.builder().client(getSSLClient()).logger(new Slf4jLogger()).logLevel( + Logger.Level.FULL).requestInterceptor(new BasicAuthRequestInterceptor(username, password)) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .target(ApiApplicationRegistrationService.class, AuthorizationConfigurationManager.getInstance().getServerURL() + @@ -82,8 +101,8 @@ public class OAuthRequestInterceptor implements RequestInterceptor { String consumerSecret = apiApplicationKey.getConsumerSecret(); String username = AuthorizationConfigurationManager.getInstance().getUserName(); String password = AuthorizationConfigurationManager.getInstance().getPassword(); - tokenIssuerService = Feign.builder().requestInterceptor( - new BasicAuthRequestInterceptor(consumerKey, consumerSecret)) + tokenIssuerService = Feign.builder().client(getSSLClient()).logger(new Slf4jLogger()).logLevel(Logger.Level.FULL) + .requestInterceptor(new BasicAuthRequestInterceptor(consumerKey, consumerSecret)) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .target(TokenIssuerService.class, AuthorizationConfigurationManager.getInstance().getTokenApiURL()); tokenInfo = tokenIssuerService.getToken(PASSWORD_GRANT_TYPE, username, password); @@ -98,4 +117,37 @@ public class OAuthRequestInterceptor implements RequestInterceptor { String headerValue = Constants.RestConstants.BEARER + tokenInfo.getAccess_token(); template.header(Constants.RestConstants.AUTHORIZATION, headerValue); } + + private static Client getSSLClient() { + return new Client.Default(getTrustedSSLSocketFactory(), new HostnameVerifier() { + @Override + public boolean verify(String s, SSLSession sslSession) { + return true; + } + }); + } + + private static SSLSocketFactory getTrustedSSLSocketFactory() { + try { + TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + public void checkClientTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + public void checkServerTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + } + }; + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, trustAllCerts, new java.security.SecureRandom()); + return sc.getSocketFactory(); + } catch (KeyManagementException | NoSuchAlgorithmException e) { + return null; + } + } + } diff --git a/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/dto/Activity.java b/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/dto/Activity.java new file mode 100644 index 000000000..b373a1c63 --- /dev/null +++ b/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/dto/Activity.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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.appmgt.mdm.restconnector.authorization.client.dto; + + +public class Activity { + + public enum Type { + CONFIG, MESSAGE, INFO, COMMAND, PROFILE, POLICY + } + private String activityId; + private String code; + private Type type; + private String createdTimeStamp; + + public String getActivityId() { + return activityId; + } + + public void setActivityId(String activityId) { + this.activityId = activityId; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + public String getCreatedTimeStamp() { + return createdTimeStamp; + } + + public void setCreatedTimeStamp(String createdTimeStamp) { + this.createdTimeStamp = createdTimeStamp; + } +} + diff --git a/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/dto/ApplicationManagementAdminService.java b/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/dto/ApplicationManagementAdminService.java index 3b390a7a8..e48e8e5c1 100644 --- a/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/dto/ApplicationManagementAdminService.java +++ b/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/dto/ApplicationManagementAdminService.java @@ -17,7 +17,6 @@ */ package org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto; -import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; import javax.ws.rs.Consumes; import javax.ws.rs.POST; diff --git a/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/dto/BasePaginatedResult.java b/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/dto/BasePaginatedResult.java deleted file mode 100644 index 64527d32f..000000000 --- a/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/dto/BasePaginatedResult.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. 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.appmgt.mdm.restconnector.authorization.client.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; - -/** - * Number of Resources. - */ -public class BasePaginatedResult { - @ApiModelProperty(value = "Number of total resources.", example = "2") - @JsonProperty("count") - private int count; - - public int getCount() { - return count; - } - - public void setCount(int count) { - this.count = count; - } -} \ No newline at end of file diff --git a/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/dto/Device.java b/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/dto/Device.java index 24916c1fa..96af8865a 100644 --- a/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/dto/Device.java +++ b/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/dto/Device.java @@ -17,10 +17,7 @@ */ package org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto; -import org.wso2.carbon.device.mgt.common.Feature; - import java.io.Serializable; -import java.util.List; /** * The DTO class of device. @@ -37,15 +34,6 @@ public class Device implements Serializable { public Device() { } - public Device(String name, String type, String description, String deviceId, EnrolmentInfo enrolmentInfo, - List features, List properties) { - this.name = name; - this.type = type; - this.description = description; - this.deviceIdentifier = deviceId; - this.enrolmentInfo = enrolmentInfo; - } - public int getId() { return id; } @@ -130,22 +118,4 @@ public class Device implements Serializable { "]" + "]"; } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (!(o instanceof org.wso2.carbon.device.mgt.common.Device)) - return false; - - org.wso2.carbon.device.mgt.common.Device device = (org.wso2.carbon.device.mgt.common.Device) o; - - return getDeviceIdentifier().equals(device.getDeviceIdentifier()); - - } - - @Override - public int hashCode() { - return getDeviceIdentifier().hashCode(); - } } diff --git a/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/dto/DeviceList.java b/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/dto/DeviceList.java index cbb866175..6470910c2 100644 --- a/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/dto/DeviceList.java +++ b/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/authorization/client/dto/DeviceList.java @@ -17,17 +17,21 @@ */ package org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; - import java.util.ArrayList; import java.util.List; -public class DeviceList extends BasePaginatedResult { +public class DeviceList { private List devices = new ArrayList<>(); + private int count; + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } - @ApiModelProperty(value = "List of devices returned") - @JsonProperty("devices") public List getList() { return devices; } diff --git a/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/internal/MDMComponent.java b/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/internal/MDMComponent.java index e1830d425..2c1e6b2f1 100644 --- a/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/internal/MDMComponent.java +++ b/components/extensions/appm-connector/org.wso2.carbon.appmgt.mdm.restconnector/src/main/java/org/wso2/carbon/appmgt/mdm/restconnector/internal/MDMComponent.java @@ -53,4 +53,4 @@ public class MDMComponent { log.debug("WSO2MDM MDM Component deactivated"); } } -} \ No newline at end of file +} diff --git a/components/extensions/appm-connector/pom.xml b/components/extensions/appm-connector/pom.xml index 2cba956a1..09f659c5b 100644 --- a/components/extensions/appm-connector/pom.xml +++ b/components/extensions/appm-connector/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.devicemgt-plugins extensions - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/pom.xml b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/pom.xml index a86b13a8d..4ac83c610 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/pom.xml +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/pom.xml @@ -20,7 +20,7 @@ org.wso2.carbon.devicemgt-plugins cdmf-transport-adapters - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../../pom.xml 4.0.0 @@ -33,6 +33,18 @@ + + org.apache.felix + maven-scr-plugin + + + generate-scr-descriptor + + scr + + + + org.apache.maven.plugins maven-surefire-plugin @@ -45,12 +57,48 @@ ${project.artifactId} ${project.artifactId} + + org.wso2.carbon.device.mgt.input.adapter.extension.internal, + org.wso2.carbon.device.mgt.input.adapter.extension.internal.* + - org.wso2.carbon.device.mgt.input.adapter.extension.* + org.wso2.carbon.device.mgt.input.adapter.extension.*, + !org.wso2.carbon.device.mgt.input.adapter.extension.internal, + + org.osgi.framework, + org.osgi.service.component, + com.jayway.jsonpath, + org.apache.commons.logging, + org.json.simple, + org.json.simple.parser + + + + + org.wso2.carbon + org.wso2.carbon.logging + + + com.googlecode.json-simple.wso2 + json-simple + + + com.jayway.jsonpath + json-path + + + org.eclipse.osgi + org.eclipse.osgi + + + org.eclipse.osgi + org.eclipse.osgi.services + + \ No newline at end of file diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/ContentTransformer.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/ContentTransformer.java index d86aaaab5..8c3b3033f 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/ContentTransformer.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/ContentTransformer.java @@ -25,6 +25,11 @@ import java.util.Map; */ public interface ContentTransformer { + /** + * This returns the type of ContentTransformer. + */ + String getType(); + /** * This is used to transform the receiver content * @param message message to be format diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/ContentValidator.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/ContentValidator.java index d01536c5a..e3e81c471 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/ContentValidator.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/ContentValidator.java @@ -24,6 +24,13 @@ import java.util.Map; * This interface will be triggered to validate the stream content before publishing. */ public interface ContentValidator { + + /** + * this returns the unique name of ContentValidatorType. + * @return + */ + String getType(); + /** * @param dynamicParameter that message. * @return ContentInfo. diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/InputAdapterExtensionService.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/InputAdapterExtensionService.java new file mode 100644 index 000000000..28046b73b --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/InputAdapterExtensionService.java @@ -0,0 +1,34 @@ +package org.wso2.carbon.device.mgt.input.adapter.extension; + +/** + * This hold the input adapter extension service. + */ +public interface InputAdapterExtensionService { + + /** + * return content validator for the given type. + * @param type type of the content validator + * @return content validator for the given type. + */ + ContentValidator getContentValidator(String type); + + /** + * return default content validator for the given type. + * @return default content validator for the given type. + */ + ContentValidator getDefaultContentValidator(); + + /** + * return content transformer for the given type. + * @param type of the content transfomer + * @return content transformer for the given type. + */ + ContentTransformer getContentTransformer(String type); + + /** + * return default content transformer for the given type. + * @return default content transformer for the given type. + */ + ContentTransformer getDefaultContentTransformer(); + +} diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/InputAdapterExtensionServiceImpl.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/InputAdapterExtensionServiceImpl.java new file mode 100644 index 000000000..5d1d33448 --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/InputAdapterExtensionServiceImpl.java @@ -0,0 +1,31 @@ +package org.wso2.carbon.device.mgt.input.adapter.extension; + +import org.wso2.carbon.device.mgt.input.adapter.extension.internal.InputAdapterServiceDataHolder; + +/** + * This hold the input adapter extension service implementation. + */ +public class InputAdapterExtensionServiceImpl implements InputAdapterExtensionService { + private static final String DEFAULT = "default"; + + + @Override + public ContentValidator getContentValidator(String type) { + return InputAdapterServiceDataHolder.getInstance().getContentValidatorMap().get(type); + } + + @Override + public ContentValidator getDefaultContentValidator() { + return InputAdapterServiceDataHolder.getInstance().getContentValidatorMap().get(DEFAULT); + } + + @Override + public ContentTransformer getContentTransformer(String type) { + return InputAdapterServiceDataHolder.getInstance().getContentTransformerMap().get(type); + } + + @Override + public ContentTransformer getDefaultContentTransformer() { + return InputAdapterServiceDataHolder.getInstance().getContentTransformerMap().get(DEFAULT); + } +} diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/internal/InputAdapterServiceComponent.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/internal/InputAdapterServiceComponent.java new file mode 100644 index 000000000..b7370fa3a --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/internal/InputAdapterServiceComponent.java @@ -0,0 +1,96 @@ +/* +* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. 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.input.adapter.extension.internal; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.service.component.ComponentContext; +import org.wso2.carbon.device.mgt.input.adapter.extension.ContentTransformer; +import org.wso2.carbon.device.mgt.input.adapter.extension.ContentValidator; +import org.wso2.carbon.device.mgt.input.adapter.extension.InputAdapterExtensionService; +import org.wso2.carbon.device.mgt.input.adapter.extension.InputAdapterExtensionServiceImpl; +import org.wso2.carbon.device.mgt.input.adapter.extension.transformer.DefaultContentTransformer; +import org.wso2.carbon.device.mgt.input.adapter.extension.validator.DefaultContentValidator; +import org.wso2.carbon.device.mgt.input.adapter.extension.validator.HTTPContentValidator; +import org.wso2.carbon.device.mgt.input.adapter.extension.validator.MQTTContentValidator; + +/** + * @scr.component name="input.adapter.extension.adapterService.component" immediate="true" + * @scr.reference name="InputAdapterServiceComponent.service" + * interface="org.wso2.carbon.device.mgt.input.adapter.extension.ContentValidator" + * cardinality="0..n" + * policy="dynamic" + * bind="setContentValidator" + * unbind="unsetContentValidator" + * * @scr.reference name="InputAdapterServiceComponent.service" + * interface="org.wso2.carbon.device.mgt.input.adapter.extension.ContentTransformer" + * cardinality="0..n" + * policy="dynamic" + * bind="setContentTransformer" + * unbind="unsetContentTransformer" + */ +public class InputAdapterServiceComponent { + + private static final Log log = LogFactory.getLog( + InputAdapterServiceComponent.class); + + protected void activate(ComponentContext context) { + try { + if (log.isDebugEnabled()) { + log.debug("Successfully deployed the input adapter extension service"); + } + + InputAdapterServiceDataHolder.getInstance().addContentTransformer(new DefaultContentTransformer()); + InputAdapterServiceDataHolder.getInstance().addContentValidator(new DefaultContentValidator()); + InputAdapterServiceDataHolder.getInstance().addContentValidator(new HTTPContentValidator()); + InputAdapterServiceDataHolder.getInstance().addContentValidator(new MQTTContentValidator()); + + context.getBundleContext().registerService(InputAdapterExtensionService.class, + new InputAdapterExtensionServiceImpl(), null); + } catch (RuntimeException e) { + log.error("Can not create the input adapter service ", e); + } + } + + protected void setContentValidator(ContentValidator contentValidator) { + if (log.isDebugEnabled()) { + log.debug("Setting ContentValidator Service"); + } + InputAdapterServiceDataHolder.getInstance().addContentValidator(contentValidator); + } + + protected void unsetContentValidator(ContentValidator contentValidator) { + if (log.isDebugEnabled()) { + log.debug("Un-setting ContentValidator Service"); + } + } + + protected void setContentTransformer(ContentTransformer contentTransformer) { + if (log.isDebugEnabled()) { + log.debug("Setting contentTransformer Service"); + } + InputAdapterServiceDataHolder.getInstance().addContentTransformer(contentTransformer); + } + + protected void unsetContentValidator(ContentTransformer contentTransformer) { + if (log.isDebugEnabled()) { + log.debug("Un-setting ContentTransformer Service"); + } + } + +} diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/internal/InputAdapterServiceDataHolder.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/internal/InputAdapterServiceDataHolder.java new file mode 100644 index 000000000..fc299ae26 --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/internal/InputAdapterServiceDataHolder.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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 org.wso2.carbon.device.mgt.input.adapter.extension.internal; + +import org.wso2.carbon.device.mgt.input.adapter.extension.ContentTransformer; +import org.wso2.carbon.device.mgt.input.adapter.extension.ContentValidator; + +import java.util.HashMap; +import java.util.Map; + +/** + * common place to hold some OSGI service references. + */ +public class InputAdapterServiceDataHolder { + + private static InputAdapterServiceDataHolder inputAdapterServiceDataHolder = new InputAdapterServiceDataHolder(); + private static Map contentValidatorMap = new HashMap<>(); + private static Map contentTransformerMap = new HashMap<>(); + + private InputAdapterServiceDataHolder() { + } + + public static InputAdapterServiceDataHolder getInstance() { + return inputAdapterServiceDataHolder; + } + + public Map getContentValidatorMap() { + return contentValidatorMap; + } + + public void addContentValidator(ContentValidator contentValidator) { + InputAdapterServiceDataHolder.contentValidatorMap.put(contentValidator.getType(), contentValidator); + } + + public Map getContentTransformerMap() { + return contentTransformerMap; + } + + public void addContentTransformer(ContentTransformer contentTransformer) { + InputAdapterServiceDataHolder.contentTransformerMap.put(contentTransformer.getType(), contentTransformer); + } +} diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/DefaultContentTransformer.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/transformer/DefaultContentTransformer.java similarity index 74% rename from components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/DefaultContentTransformer.java rename to components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/transformer/DefaultContentTransformer.java index 9e0f5f256..fe73bd37f 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/DefaultContentTransformer.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/transformer/DefaultContentTransformer.java @@ -16,14 +16,22 @@ * under the License. */ -package org.wso2.carbon.device.mgt.input.adapter.extension; +package org.wso2.carbon.device.mgt.input.adapter.extension.transformer; + +import org.wso2.carbon.device.mgt.input.adapter.extension.ContentTransformer; import java.util.Map; /** * This holds the default implementation of ContentTransformer */ -public class DefaultContentTransformer implements ContentTransformer{ +public class DefaultContentTransformer implements ContentTransformer { + private static final String DEFAULT_CONTENT_VALIDATOR = "default"; + + @Override + public String getType() { + return DEFAULT_CONTENT_VALIDATOR; + } @Override public Object transform(Object message, Map dynamicProperties) { diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/DefaultContentValidator.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/validator/DefaultContentValidator.java similarity index 73% rename from components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/DefaultContentValidator.java rename to components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/validator/DefaultContentValidator.java index 3e507b10d..2493c0dd8 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/DefaultContentValidator.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/validator/DefaultContentValidator.java @@ -16,7 +16,10 @@ * under the License. */ -package org.wso2.carbon.device.mgt.input.adapter.extension; +package org.wso2.carbon.device.mgt.input.adapter.extension.validator; + +import org.wso2.carbon.device.mgt.input.adapter.extension.ContentInfo; +import org.wso2.carbon.device.mgt.input.adapter.extension.ContentValidator; import java.util.Map; @@ -24,6 +27,12 @@ import java.util.Map; * This holds the default implementation of content validator interface. */ public class DefaultContentValidator implements ContentValidator { + private static final String DEFAULT_TYPE = "default"; + + @Override + public String getType() { + return DEFAULT_TYPE; + } @Override public ContentInfo validate(Object message, Map dynamicParams) { diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/validator/HTTPContentValidator.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/validator/HTTPContentValidator.java new file mode 100644 index 000000000..fe548099a --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/validator/HTTPContentValidator.java @@ -0,0 +1,87 @@ +/* +* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. 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.input.adapter.extension.validator; + +import com.jayway.jsonpath.JsonPath; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.json.simple.JSONArray; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.wso2.carbon.device.mgt.input.adapter.extension.ContentInfo; +import org.wso2.carbon.device.mgt.input.adapter.extension.ContentValidator; + +import java.util.List; +import java.util.Map; + +public class HTTPContentValidator implements ContentValidator { + private static final Log log = LogFactory.getLog(HTTPContentValidator.class); + private static String JSON_ARRAY_START_CHAR = "["; + private static String CDMF_SCOPE_PREFIX = "cdmf"; + private static String CDMF_SCOPE_SEPERATOR = "/"; + private static String CDMF_HTTP_CONTENT_VALIDATOR = "iot-http"; + public static final String DEVICE_ID_JSON_PATH = "event.metaData.deviceId"; + + @Override + public String getType() { + return CDMF_HTTP_CONTENT_VALIDATOR; + } + + @Override + public ContentInfo validate(Object msgPayload, Map dynamicParams) { + String deviceId = (String) dynamicParams.get("deviceId"); + String msg = (String) msgPayload; + String deviceIdJsonPath = DEVICE_ID_JSON_PATH; + boolean status; + if (msg.startsWith(JSON_ARRAY_START_CHAR)) { + status = processMultipleEvents(msg, deviceId, deviceIdJsonPath); + } else { + status = processSingleEvent(msg, deviceId, deviceIdJsonPath); + } + return new ContentInfo(status, msg); + } + + private boolean processSingleEvent(String msg, String deviceIdFromTopic, String deviceIdJsonPath) { + Object res = JsonPath.read(msg, deviceIdJsonPath); + String deviceIdFromContent = (res != null) ? res.toString() : ""; + if (deviceIdFromContent.equals(deviceIdFromTopic)) { + return true; + } + return false; + } + + private boolean processMultipleEvents(String msg, String deviceIdFromTopic, String deviceIdJsonPath) { + try { + JSONParser jsonParser = new JSONParser(); + JSONArray jsonArray = (JSONArray) jsonParser.parse(msg); + boolean status = false; + for (int i = 0; i < jsonArray.size(); i++) { + status = processSingleEvent(jsonArray.get(i).toString(), deviceIdFromTopic, deviceIdJsonPath); + if (!status) { + return status; + } + } + return status; + } catch (ParseException e) { + log.error("Invalid input " + msg, e); + return false; + } + } + +} diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/MQTTContentValidator.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/validator/MQTTContentValidator.java similarity index 81% rename from components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/MQTTContentValidator.java rename to components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/validator/MQTTContentValidator.java index a3de8ffa9..fdd4c34cf 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/MQTTContentValidator.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/input/adapter/extension/validator/MQTTContentValidator.java @@ -16,7 +16,7 @@ * under the License. */ -package org.wso2.carbon.device.mgt.input.adapter.mqtt.util; +package org.wso2.carbon.device.mgt.input.adapter.extension.validator; import com.jayway.jsonpath.JsonPath; import org.apache.commons.logging.Log; @@ -32,13 +32,23 @@ import java.util.Map; public class MQTTContentValidator implements ContentValidator { private static final String JSON_ARRAY_START_CHAR = "["; private static final Log log = LogFactory.getLog(MQTTContentValidator.class); + private static final String CDMF_MQTT_CONTENT_VALIDATOR = "iot-mqtt"; + public static final String DEVICE_ID_JSON_PATH = "event.metaData.deviceId"; + public static final String DEVICE_TYPE_JSON_PATH = "event.metaData.deviceId"; + public static final String TOPIC = "topic"; + public static final int DEVICE_ID_TOPIC_HIERARCHY_INDEX = 2; + + @Override + public String getType() { + return null; + } @Override public ContentInfo validate(Object msgPayload, Map dynamicParams) { - String topic = (String) dynamicParams.get(MQTTEventAdapterConstants.TOPIC); + String topic = (String) dynamicParams.get(TOPIC); String topics[] = topic.split("/"); - String deviceIdJsonPath = MQTTEventAdapterConstants.DEVICE_ID_JSON_PATH; - int deviceIdInTopicHierarchyLevelIndex = MQTTEventAdapterConstants.DEVICE_ID_TOPIC_HIERARCHY_INDEX; + String deviceIdJsonPath = DEVICE_ID_JSON_PATH; + int deviceIdInTopicHierarchyLevelIndex = DEVICE_ID_TOPIC_HIERARCHY_INDEX; String deviceIdFromTopic = topics[deviceIdInTopicHierarchyLevelIndex]; boolean status; String message = (String) msgPayload; diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/pom.xml b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/pom.xml index 282f33f64..6a42b3f56 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/pom.xml +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/pom.xml @@ -20,7 +20,7 @@ org.wso2.carbon.devicemgt-plugins cdmf-transport-adapters - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../../pom.xml @@ -76,6 +76,26 @@ commons-pool.wso2 commons-pool + + io.github.openfeign + feign-core + + + io.github.openfeign + feign-jaxrs + + + io.github.openfeign + feign-gson + + + javax.ws.rs + jsr311-api + + + io.github.openfeign + feign-slf4j + @@ -117,7 +137,6 @@ org.wso2.carbon.event.input.adapter.core, org.wso2.carbon.event.input.adapter.core.*, javax.xml.namespace; version=0.0.0, - com.jayway.jsonpath.*, com.nimbusds.jose, com.nimbusds.jose.crypto, com.nimbusds.jwt, @@ -130,9 +149,29 @@ org.wso2.carbon.user.core.service, org.wso2.carbon.user.core.tenant, org.apache.commons.pool, - org.apache.commons.pool.impl + org.apache.commons.pool.impl, + feign, + feign.auth, + feign.codec, + feign.gson, + org.wso2.carbon.device.mgt.input.adapter.extension, + org.apache.axiom.util.base64, + org.apache.axis2.*, + org.apache.commons.httpclient.*, + org.apache.commons.logging, + org.apache.log4j, + org.wso2.carbon.context, + org.wso2.carbon.core.util, + org.wso2.carbon.identity.oauth2.*, + org.wso2.carbon.utils, + org.wso2.carbon.utils.multitenancy, + javax.net.ssl, + feign.slf4j - * + + jsr311-api, + feign-jaxrs + diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/HTTPEventAdapterFactory.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/HTTPEventAdapterFactory.java index b46117f65..c12e24a6a 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/HTTPEventAdapterFactory.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/HTTPEventAdapterFactory.java @@ -76,12 +76,12 @@ public class HTTPEventAdapterFactory extends InputEventAdapterFactory { propertyList.add(exposedTransportsProperty); //Content Validator details - Property contentValidator = new Property(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME); + Property contentValidator = new Property(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_TYPE); contentValidator.setDisplayName( - resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME)); + resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_TYPE)); contentValidator.setRequired(false); contentValidator.setHint( - resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME_HINT)); + resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_TYPE_HINT)); contentValidator.setDefaultValue(HTTPEventAdapterConstants.DEFAULT); propertyList.add(contentValidator); diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/HTTPMessageServlet.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/HTTPMessageServlet.java index 3d5351b30..afda05edf 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/HTTPMessageServlet.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/HTTPMessageServlet.java @@ -18,11 +18,13 @@ package org.wso2.carbon.device.mgt.input.adapter.http; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.input.adapter.http.authorization.DeviceAuthorizer; +import org.wso2.carbon.device.mgt.input.adapter.http.internal.InputAdapterServiceDataHolder; import org.wso2.carbon.device.mgt.input.adapter.http.oauth.OAuthAuthenticator; import org.wso2.carbon.device.mgt.input.adapter.extension.ContentInfo; import org.wso2.carbon.device.mgt.input.adapter.extension.ContentTransformer; -import org.wso2.carbon.device.mgt.input.adapter.extension.DefaultContentTransformer; -import org.wso2.carbon.device.mgt.input.adapter.extension.DefaultContentValidator; +import org.wso2.carbon.device.mgt.input.adapter.extension.transformer.DefaultContentTransformer; +import org.wso2.carbon.device.mgt.input.adapter.extension.validator.DefaultContentValidator; import org.wso2.carbon.device.mgt.input.adapter.http.exception.HTTPContentInitializationException; import org.wso2.carbon.device.mgt.input.adapter.http.jwt.JWTAuthenticator; import org.wso2.carbon.device.mgt.input.adapter.http.util.AuthenticationInfo; @@ -58,6 +60,7 @@ public class HTTPMessageServlet extends HttpServlet { private String exposedTransports; private static JWTAuthenticator jwtAuthenticator; private static OAuthAuthenticator oAuthAuthenticator; + private static DeviceAuthorizer deviceAuthorizer; public HTTPMessageServlet(InputEventAdapterListener eventAdaptorListener, int tenantId, InputEventAdapterConfiguration eventAdapterConfiguration, @@ -67,48 +70,29 @@ public class HTTPMessageServlet extends HttpServlet { this.exposedTransports = eventAdapterConfiguration.getProperties().get( HTTPEventAdapterConstants.EXPOSED_TRANSPORTS); - String className = eventAdapterConfiguration.getProperties().get( - HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME); - if (HTTPEventAdapterConstants.DEFAULT.equals(className)) { - contentValidator = new DefaultContentValidator(); + String contentValidatorType = eventAdapterConfiguration.getProperties().get( + HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_TYPE); + if (contentValidatorType == null || HTTPEventAdapterConstants.DEFAULT.equals(contentValidatorType)) { + contentValidator = InputAdapterServiceDataHolder.getInputAdapterExtensionService() + .getDefaultContentValidator(); } else { - try { - Class contentValidatorClass = Class.forName(className) - .asSubclass(ContentValidator.class); - contentValidator = contentValidatorClass.newInstance(); - } catch (ClassNotFoundException e) { - throw new HTTPContentInitializationException( - "Unable to find the class validator: " + className, e); - } catch (InstantiationException e) { - throw new HTTPContentInitializationException( - "Unable to create an instance of :" + className, e); - } catch (IllegalAccessException e) { - throw new HTTPContentInitializationException("Access of the instance in not allowed.", e); - } + contentValidator = InputAdapterServiceDataHolder.getInputAdapterExtensionService() + .getContentValidator(contentValidatorType); } String contentTransformerClassName = eventAdapterConfiguration.getProperties().get( HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME); - if (contentTransformerClassName != null && contentTransformerClassName.equals(HTTPEventAdapterConstants.DEFAULT)) { - contentTransformer = new DefaultContentTransformer(); - } else if (contentTransformerClassName != null && !contentTransformerClassName.isEmpty()) { - try { - Class contentTransformerClass = Class.forName(contentTransformerClassName) - .asSubclass(ContentTransformer.class); - contentTransformer = contentTransformerClass.newInstance(); - } catch (ClassNotFoundException e) { - throw new HTTPContentInitializationException( - "Unable to find the class transformer: " + contentTransformerClassName, e); - } catch (InstantiationException e) { - throw new HTTPContentInitializationException( - "Unable to create an instance of :" + contentTransformerClassName, e); - } catch (IllegalAccessException e) { - throw new HTTPContentInitializationException("Access of the instance in not allowed.", e); - } + if (contentTransformerClassName == null || contentTransformerClassName.equals(HTTPEventAdapterConstants.DEFAULT)) { + contentTransformer = InputAdapterServiceDataHolder.getInputAdapterExtensionService() + .getDefaultContentTransformer(); + } else { + contentTransformer = InputAdapterServiceDataHolder.getInputAdapterExtensionService() + .getContentTransformer(contentValidatorType); } jwtAuthenticator = new JWTAuthenticator(); oAuthAuthenticator = new OAuthAuthenticator(globalProperties); + deviceAuthorizer = new DeviceAuthorizer(globalProperties); } @Override @@ -177,14 +161,24 @@ public class HTTPMessageServlet extends HttpServlet { paramMap.put(HTTPEventAdapterConstants.USERNAME_TAG, authenticationInfo.getUsername()); paramMap.put(HTTPEventAdapterConstants.TENANT_DOMAIN_TAG, authenticationInfo.getTenantDomain()); paramMap.put(HTTPEventAdapterConstants.SCOPE_TAG, authenticationInfo.getScopes()); - if (contentValidator != null && contentTransformer != null) { - data = (String) contentTransformer.transform(data, paramMap); - ContentInfo contentInfo = contentValidator.validate(data, paramMap); - if (contentInfo != null && contentInfo.isValidContent()) { - HTTPEventAdapter.executorService.submit(new HTTPRequestProcessor(eventAdaptorListener, - (String) contentInfo.getMessage(), tenantId)); - } - } + String deviceId = (String) paramMap.get("deviceId"); + String deviceType = (String) paramMap.get("deviceType"); + if (deviceAuthorizer.isAuthorized(authenticationInfo, deviceId, deviceType)) { + if (contentValidator != null && contentTransformer != null) { + data = (String) contentTransformer.transform(data, paramMap); + ContentInfo contentInfo = contentValidator.validate(data, paramMap); + if (contentInfo != null && contentInfo.isValidContent()) { + HTTPEventAdapter.executorService.submit(new HTTPRequestProcessor(eventAdaptorListener, + (String) contentInfo + .getMessage(), + tenantId)); + } + } + } else { + if (log.isDebugEnabled()) { + log.debug("Unauthorized device with device id" + deviceId + " and device type" + deviceType); + } + } } } diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/DeviceAuthorizer.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/DeviceAuthorizer.java new file mode 100644 index 000000000..c6e195254 --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/DeviceAuthorizer.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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.input.adapter.http.authorization; + +import feign.Client; +import feign.Feign; +import feign.FeignException; +import feign.Logger; +import feign.Request; +import feign.Response; +import feign.gson.GsonDecoder; +import feign.gson.GsonEncoder; +import feign.jaxrs.JAXRSContract; +import feign.slf4j.Slf4jLogger; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.input.adapter.http.authorization.client.OAuthRequestInterceptor; +import org.wso2.carbon.device.mgt.input.adapter.http.authorization.client.dto.AuthorizationRequest; +import org.wso2.carbon.device.mgt.input.adapter.http.authorization.client.dto.DeviceAccessAuthorizationAdminService; +import org.wso2.carbon.device.mgt.input.adapter.http.authorization.client.dto.DeviceAuthorizationResult; +import org.wso2.carbon.device.mgt.input.adapter.http.authorization.client.dto.DeviceIdentifier; +import org.wso2.carbon.device.mgt.input.adapter.http.util.AuthenticationInfo; +import org.wso2.carbon.device.mgt.input.adapter.http.util.PropertyUtils; +import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterException; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * This authorizer crossvalidates the request with device id and device type. + */ +public class DeviceAuthorizer { + + private static DeviceAccessAuthorizationAdminService deviceAccessAuthorizationAdminService; + private static final String CDMF_SERVER_BASE_CONTEXT = "/api/device-mgt/v1.0"; + private static final String DEVICE_MGT_SERVER_URL = "deviceMgtServerUrl"; + private static Log log = LogFactory.getLog(DeviceAuthorizer.class); + + public DeviceAuthorizer(Map globalProperties) { + try { + deviceAccessAuthorizationAdminService = Feign.builder().client(getSSLClient()).logger(new Slf4jLogger()) + .logLevel(Logger.Level.FULL).requestInterceptor(new OAuthRequestInterceptor(globalProperties)) + .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) + .target(DeviceAccessAuthorizationAdminService.class, getDeviceMgtServerUrl(globalProperties) + + CDMF_SERVER_BASE_CONTEXT); + } catch (InputEventAdapterException e) { + log.error("Invalid value for deviceMgtServerUrl in globalProperties."); + } + } + + + public boolean isAuthorized(AuthenticationInfo authenticationInfo, String deviceId, String deviceType) { + + if (deviceId != null && !deviceId.isEmpty() && deviceType != null && !deviceType.isEmpty()) { + + AuthorizationRequest authorizationRequest = new AuthorizationRequest(); + authorizationRequest.setTenantDomain(authenticationInfo.getTenantDomain()); + authorizationRequest.setUsername(authenticationInfo.getUsername()); + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(deviceId); + deviceIdentifier.setType(deviceType); + List deviceIdentifiers = new ArrayList<>(); + deviceIdentifiers.add(deviceIdentifier); + authorizationRequest.setDeviceIdentifiers(deviceIdentifiers); + try { + DeviceAuthorizationResult deviceAuthorizationResult = + deviceAccessAuthorizationAdminService.isAuthorized(authorizationRequest); + List devices = deviceAuthorizationResult.getAuthorizedDevices(); + if (devices != null && devices.size() > 0) { + DeviceIdentifier authorizedDevice = devices.get(0); + if (authorizedDevice.getId().equals(deviceId) && authorizedDevice.getType().equals(deviceType)) { + return true; + } + } + } catch (FeignException e) { + log.error(e.getMessage(), e); + } + } + return false; + } + + private String getDeviceMgtServerUrl(Map properties) throws InputEventAdapterException { + String deviceMgtServerUrl = PropertyUtils.replaceProperty(properties.get(DEVICE_MGT_SERVER_URL)); + if (deviceMgtServerUrl == null || deviceMgtServerUrl.isEmpty()) { + log.error("deviceMgtServerUrl can't be empty "); + } + return deviceMgtServerUrl; + } + + private static Client getSSLClient() { + return new Client.Default(getTrustedSSLSocketFactory(), new HostnameVerifier() { + @Override + public boolean verify(String s, SSLSession sslSession) { + return true; + } + }); + } + + private static SSLSocketFactory getTrustedSSLSocketFactory() { + try { + TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + public void checkClientTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + public void checkServerTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + } + }; + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, trustAllCerts, new java.security.SecureRandom()); + return sc.getSocketFactory(); + } catch (KeyManagementException | NoSuchAlgorithmException e) { + return null; + } + } + +} \ No newline at end of file diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/OAuthRequestInterceptor.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/OAuthRequestInterceptor.java new file mode 100755 index 000000000..0c6eff5d8 --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/OAuthRequestInterceptor.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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 org.wso2.carbon.device.mgt.input.adapter.http.authorization.client; + +import feign.Client; +import feign.Feign; +import feign.Logger; +import feign.Request; +import feign.RequestInterceptor; +import feign.RequestTemplate; +import feign.Response; +import feign.auth.BasicAuthRequestInterceptor; +import feign.gson.GsonDecoder; +import feign.gson.GsonEncoder; +import feign.jaxrs.JAXRSContract; +import feign.slf4j.Slf4jLogger; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.input.adapter.http.authorization.client.dto.AccessTokenInfo; +import org.wso2.carbon.device.mgt.input.adapter.http.authorization.client.dto.ApiApplicationKey; +import org.wso2.carbon.device.mgt.input.adapter.http.authorization.client.dto.ApiApplicationRegistrationService; +import org.wso2.carbon.device.mgt.input.adapter.http.authorization.client.dto.ApiRegistrationProfile; +import org.wso2.carbon.device.mgt.input.adapter.http.authorization.client.dto.TokenIssuerService; +import org.wso2.carbon.device.mgt.input.adapter.http.util.PropertyUtils; +import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterException; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.util.Map; + +/** + * This is a request interceptor to add oauth token header. + */ +public class OAuthRequestInterceptor implements RequestInterceptor { + + private AccessTokenInfo tokenInfo; + private long refreshTimeOffset; + private static final String API_APPLICATION_REGISTRATION_CONTEXT = "/api-application-registration"; + private static final String DEVICE_MANAGEMENT_SERVICE_TAG[] = {"device_management"}; + private static final String APPLICATION_NAME = "websocket-app"; + private static final String PASSWORD_GRANT_TYPE = "password"; + private static final String REFRESH_GRANT_TYPE = "refresh_token"; + private static final String REQUIRED_SCOPE = "perm:authorization:verify"; + private ApiApplicationRegistrationService apiApplicationRegistrationService; + private TokenIssuerService tokenIssuerService; + + private static Log log = LogFactory.getLog(OAuthRequestInterceptor.class); + + private static final String CONNECTION_USERNAME = "username"; + private static final String CONNECTION_PASSWORD = "password"; + private static final String TOKEN_REFRESH_TIME_OFFSET = "tokenRefreshTimeOffset"; + private static final String TOKEN_SCOPES = "scopes"; + private static final String DEVICE_MGT_SERVER_URL = "deviceMgtServerUrl"; + private static final String TOKEN_ENDPOINT_CONTEXT = "tokenUrl"; + private static String username; + private static String password; + private static String tokenEndpoint; + private static String deviceMgtServerUrl; + private static String scopes; + private static Map globalProperties; + + + /** + * Creates an interceptor that authenticates all requests. + */ + public OAuthRequestInterceptor(Map globalProperties) { + this.globalProperties = globalProperties; + try { + deviceMgtServerUrl = getDeviceMgtServerUrl(globalProperties); + refreshTimeOffset = getRefreshTimeOffset(globalProperties) * 1000; + username = getUsername(globalProperties); + password = getPassword(globalProperties); + tokenEndpoint = getTokenEndpoint(globalProperties); + apiApplicationRegistrationService = Feign.builder().client(getSSLClient()).logger(new Slf4jLogger()).logLevel( + Logger.Level.FULL).requestInterceptor(new BasicAuthRequestInterceptor(username, password)) + .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) + .target(ApiApplicationRegistrationService.class, + deviceMgtServerUrl + API_APPLICATION_REGISTRATION_CONTEXT); + } catch (InputEventAdapterException e) { + log.error("Invalid url: deviceMgtServerUrl" + deviceMgtServerUrl + " or tokenEndpoint:" + tokenEndpoint, + e); + } + } + + @Override + public void apply(RequestTemplate template) { + if (tokenInfo == null) { + //had to do on demand initialization due to start up error. + ApiRegistrationProfile apiRegistrationProfile = new ApiRegistrationProfile(); + apiRegistrationProfile.setApplicationName(APPLICATION_NAME); + apiRegistrationProfile.setIsAllowedToAllDomains(false); + apiRegistrationProfile.setIsMappingAnExistingOAuthApp(false); + apiRegistrationProfile.setTags(DEVICE_MANAGEMENT_SERVICE_TAG); + ApiApplicationKey apiApplicationKey = apiApplicationRegistrationService.register(apiRegistrationProfile); + String consumerKey = apiApplicationKey.getConsumerKey(); + String consumerSecret = apiApplicationKey.getConsumerSecret(); + tokenIssuerService = Feign.builder().client(getSSLClient()) + .logger(new Slf4jLogger()).logLevel(Logger.Level.FULL) + .requestInterceptor(new BasicAuthRequestInterceptor(consumerKey, consumerSecret)) + .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) + .target(TokenIssuerService.class, tokenEndpoint); + tokenInfo = tokenIssuerService.getToken(PASSWORD_GRANT_TYPE, username, password, REQUIRED_SCOPE); + tokenInfo.setExpires_in(System.currentTimeMillis() + (tokenInfo.getExpires_in() * 1000)); + } + synchronized(this) { + if (System.currentTimeMillis() + refreshTimeOffset > tokenInfo.getExpires_in()) { + tokenInfo = tokenIssuerService.getToken(REFRESH_GRANT_TYPE, tokenInfo.getRefresh_token()); + tokenInfo.setExpires_in(System.currentTimeMillis() + tokenInfo.getExpires_in()); + } + } + String headerValue = "Bearer " + tokenInfo.getAccess_token(); + template.header("Authorization", headerValue); + } + + private String getUsername(Map globalProperties) { + String username = globalProperties.get(CONNECTION_USERNAME); + if (username == null || username.isEmpty()) { + log.error("username can't be empty "); + } + return username; + } + + private String getPassword(Map globalProperties) { + String password = globalProperties.get(CONNECTION_PASSWORD);; + if (password == null || password.isEmpty()) { + log.error("password can't be empty "); + } + return password; + } + + private String getDeviceMgtServerUrl(Map globalProperties) throws InputEventAdapterException { + String deviceMgtServerUrl = globalProperties.get(DEVICE_MGT_SERVER_URL); + if (deviceMgtServerUrl == null || deviceMgtServerUrl.isEmpty()) { + log.error("deviceMgtServerUrl can't be empty "); + } + return PropertyUtils.replaceProperty(deviceMgtServerUrl); + } + + private String getTokenEndpoint(Map globalProperties) throws InputEventAdapterException { + String tokenEndpoint = globalProperties.get(TOKEN_ENDPOINT_CONTEXT); + if ( tokenEndpoint.isEmpty()) { + log.error("tokenEndpoint can't be empty "); + } + return PropertyUtils.replaceProperty(tokenEndpoint); + } + + private long getRefreshTimeOffset(Map globalProperties) { + long refreshTimeOffset = 100; + try { + refreshTimeOffset = Long.parseLong(globalProperties.get(TOKEN_REFRESH_TIME_OFFSET)); + } catch (NumberFormatException e) { + log.error("refreshTimeOffset should be a number", e); + } + return refreshTimeOffset; + } + + private static Client getSSLClient() { + return new Client.Default(getTrustedSSLSocketFactory(), new HostnameVerifier() { + @Override + public boolean verify(String s, SSLSession sslSession) { + return true; + } + }); + } + + private static SSLSocketFactory getTrustedSSLSocketFactory() { + try { + TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + public void checkClientTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + public void checkServerTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + } + }; + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, trustAllCerts, new java.security.SecureRandom()); + return sc.getSocketFactory(); + } catch (KeyManagementException | NoSuchAlgorithmException e) { + return null; + } + } +} diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/AccessTokenInfo.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/AccessTokenInfo.java new file mode 100755 index 000000000..a935d8587 --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/AccessTokenInfo.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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 org.wso2.carbon.device.mgt.input.adapter.http.authorization.client.dto; + +/** + * This hold access token info that returned from the api call + */ +public class AccessTokenInfo { + public String token_type; + public long expires_in; + public String refresh_token; + public String access_token; + + public String getToken_type() { + return token_type; + } + + public void setToken_type(String token_type) { + this.token_type = token_type; + } + + public long getExpires_in() { + return expires_in; + } + + public void setExpires_in(long expires_in) { + this.expires_in = expires_in; + } + + public String getRefresh_token() { + return refresh_token; + } + + public void setRefresh_token(String refresh_token) { + this.refresh_token = refresh_token; + } + + public String getAccess_token() { + return access_token; + } + + public void setAccess_token(String access_token) { + this.access_token = access_token; + } +} diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/ApiApplicationKey.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/ApiApplicationKey.java new file mode 100644 index 000000000..cfc32a4be --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/ApiApplicationKey.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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.input.adapter.http.authorization.client.dto; + +/** + * This holds api application consumer key and secret. + */ +public class ApiApplicationKey { + private String client_id; + private String client_secret; + + public String getConsumerKey() { + return this.client_id; + } + + public void setClient_id(String consumerKey) { + this.client_id = consumerKey; + } + + public String getConsumerSecret() { + return this.client_secret; + } + + public void setClient_secret(String consumerSecret) { + this.client_secret = consumerSecret; + } +} diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/ApiApplicationRegistrationService.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/ApiApplicationRegistrationService.java new file mode 100755 index 000000000..b8e216305 --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/ApiApplicationRegistrationService.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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 org.wso2.carbon.device.mgt.input.adapter.http.authorization.client.dto; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +/** + * This is the application registration service that exposed for apimApplicationRegistration + */ + +@Path("/register") +public interface ApiApplicationRegistrationService { + + /** + * This method is used to register api application + * + * @param registrationProfile contains the necessary attributes that are needed in order to register an app. + */ + @POST + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + ApiApplicationKey register(ApiRegistrationProfile registrationProfile); +} diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/ApiRegistrationProfile.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/ApiRegistrationProfile.java new file mode 100755 index 000000000..51748f4a3 --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/ApiRegistrationProfile.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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 org.wso2.carbon.device.mgt.input.adapter.http.authorization.client.dto; + + +/** + * This class represents the data that are required to register + * the oauth application. + */ +public class ApiRegistrationProfile { + + public String applicationName; + public String tags[]; + public boolean isAllowedToAllDomains; + public String consumerKey; + public String consumerSecret; + public boolean isMappingAnExistingOAuthApp; + + public String getApplicationName() { + return applicationName; + } + + public void setApplicationName(String applicationName) { + this.applicationName = applicationName; + } + + public String[] getTags() { + return tags; + } + + public void setTags(String[] tags) { + this.tags = tags; + } + + public boolean isAllowedToAllDomains() { + return isAllowedToAllDomains; + } + + public void setIsAllowedToAllDomains(boolean isAllowedToAllDomains) { + this.isAllowedToAllDomains = isAllowedToAllDomains; + } + + public boolean isMappingAnExistingOAuthApp() { + return isMappingAnExistingOAuthApp; + } + + public void setIsMappingAnExistingOAuthApp(boolean isMappingAnExistingOAuthApp) { + this.isMappingAnExistingOAuthApp = isMappingAnExistingOAuthApp; + } + + public String getConsumerKey() { + return consumerKey; + } + + public void setConsumerKey(String consumerKey) { + this.consumerKey = consumerKey; + } + + public String getConsumerSecret() { + return consumerSecret; + } + + public void setConsumerSecret(String consumerSecret) { + this.consumerSecret = consumerSecret; + } +} \ No newline at end of file diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/AuthorizationRequest.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/AuthorizationRequest.java new file mode 100644 index 000000000..8703e6d1a --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/AuthorizationRequest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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 org.wso2.carbon.device.mgt.input.adapter.http.authorization.client.dto; + +import java.util.List; + +/** + * DTO of the authorization request + */ +public class AuthorizationRequest { + + String tenantDomain; + String username; + List deviceIdentifiers; + List permissions; + + public String getTenantDomain() { + return tenantDomain; + } + + public void setTenantDomain(String tenantDomain) { + this.tenantDomain = tenantDomain; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public List getDeviceIdentifiers() { + return deviceIdentifiers; + } + + public void setDeviceIdentifiers(List deviceIdentifiers) { + this.deviceIdentifiers = deviceIdentifiers; + } + + public List getPermissions() { + return permissions; + } + + public void setPermissions(List permissions) { + this.permissions = permissions; + } +} diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/DeviceAccessAuthorizationAdminService.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/DeviceAccessAuthorizationAdminService.java new file mode 100644 index 000000000..9c4c74140 --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/DeviceAccessAuthorizationAdminService.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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.input.adapter.http.authorization.client.dto; + + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + + +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Path("/admin/authorization") +/** + * This interface provided the definition of the device - user access verification service. + */ +public interface DeviceAccessAuthorizationAdminService { + + @POST + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + DeviceAuthorizationResult isAuthorized(AuthorizationRequest authorizationRequest); +} diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/DeviceAuthorizationResult.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/DeviceAuthorizationResult.java new file mode 100644 index 000000000..2a27ba6b1 --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/DeviceAuthorizationResult.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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.input.adapter.http.authorization.client.dto; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a DeviceAuthorizationResult including a list of authorized devices and a list of unauthorized devices. + */ +public class DeviceAuthorizationResult { + + private List authorizedDevices = new ArrayList<>(); + private List unauthorizedDevices = new ArrayList<>(); + + public List getAuthorizedDevices() { + return authorizedDevices; + } + + public void setAuthorizedDevices(List authorizedDevices) { + this.authorizedDevices = authorizedDevices; + } + + public void setUnauthorizedDevices( + List unauthorizedDevices) { + this.unauthorizedDevices = unauthorizedDevices; + } + + public void addAuthorizedDevice(DeviceIdentifier deviceIdentifier) { + authorizedDevices.add(deviceIdentifier); + } + + public List getUnauthorizedDevices() { + return unauthorizedDevices; + } + + public void addUnauthorizedDevice(DeviceIdentifier deviceIdentifier) { + unauthorizedDevices.add(deviceIdentifier); + } +} diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/DeviceIdentifier.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/DeviceIdentifier.java new file mode 100644 index 000000000..872af37f9 --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/DeviceIdentifier.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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.input.adapter.http.authorization.client.dto; + +import java.io.Serializable; + +/** + * DTO of the device identifier + */ +public class DeviceIdentifier implements Serializable{ + + private String id; + private String type; + + public DeviceIdentifier() {} + + public DeviceIdentifier(String id, String type) { + this.id = id; + this.type = type; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type.toLowerCase(); + } + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } +} diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/OAuthApplicationInfo.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/OAuthApplicationInfo.java new file mode 100755 index 000000000..b396c863d --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/OAuthApplicationInfo.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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 org.wso2.carbon.device.mgt.input.adapter.http.authorization.client.dto; + +/** + * This class represents an OAuth application populated with necessary data. + */ +public class OAuthApplicationInfo { + + public String client_id; + public String client_name; + public String callback_url; + public String client_secret; + + public String getClient_id() { + return client_id; + } + + public void setClient_id(String client_id) { + this.client_id = client_id; + } + + public String getClient_name() { + return client_name; + } + + public void setClient_name(String client_name) { + this.client_name = client_name; + } + + public String getCallback_url() { + return callback_url; + } + + public void setCallback_url(String callback_url) { + this.callback_url = callback_url; + } + + public String getClient_secret() { + return client_secret; + } + + public void setClient_secret(String client_secret) { + this.client_secret = client_secret; + } +} diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/RegisterInfo.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/RegisterInfo.java new file mode 100755 index 000000000..4bb046b48 --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/RegisterInfo.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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 org.wso2.carbon.device.mgt.input.adapter.http.authorization.client.dto; + +/** + * This holds the data related to registration. + */ +public class RegisterInfo { + + private boolean isRegistered; + private String msg; + + public boolean isRegistered() { + return isRegistered; + } + + public void setIsRegistered(boolean isRegistered) { + this.isRegistered = isRegistered; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } +} diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/RegistrationProfile.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/RegistrationProfile.java new file mode 100755 index 000000000..0ed5cfbe3 --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/RegistrationProfile.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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 org.wso2.carbon.device.mgt.input.adapter.http.authorization.client.dto; + + +/** + * This class represents the data that are required to register + * the oauth application. + */ +public class RegistrationProfile { + + public String callbackUrl; + public String clientName; + public String tokenScope; + public String owner; + public String grantType; + public String applicationType; + + public String getCallbackUrl() { + return callbackUrl; + } + + public void setCallbackUrl(String callBackUrl) { + this.callbackUrl = callBackUrl; + } + + public String getClientName() { + return clientName; + } + + public void setClientName(String clientName) { + this.clientName = clientName; + } + + public String getTokenScope() { + return tokenScope; + } + + public void setTokenScope(String tokenScope) { + this.tokenScope = tokenScope; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public String getGrantType() { + return grantType; + } + + public void setGrantType(String grantType) { + this.grantType = grantType; + } + + public String getApplicationType() { + return applicationType; + } + + public void setApplicationType(String applicationType) { + this.applicationType = applicationType; + } + +} \ No newline at end of file diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/TokenIssuerService.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/TokenIssuerService.java new file mode 100755 index 000000000..950d05291 --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/authorization/client/dto/TokenIssuerService.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + * + */ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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 org.wso2.carbon.device.mgt.input.adapter.http.authorization.client.dto; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +/** + * This hold the api defintion that is used as a contract with netflix feign. + */ +public interface TokenIssuerService { + + @POST + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + AccessTokenInfo getToken(@QueryParam("grant_type") String grant, @QueryParam("username") String username, + @QueryParam("password") String password); + + @POST + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + AccessTokenInfo getToken(@QueryParam("grant_type") String grant, @QueryParam("username") String username, + @QueryParam("password") String password, @QueryParam("scope") String scopes); + + @POST + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + AccessTokenInfo getToken(@QueryParam("grant_type") String grant, @QueryParam("refresh_token") String refreshToken); +} \ No newline at end of file diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/internal/InputAdapterServiceComponent.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/internal/InputAdapterServiceComponent.java index 7e5688838..cd3876c8f 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/internal/InputAdapterServiceComponent.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/internal/InputAdapterServiceComponent.java @@ -21,6 +21,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.osgi.service.component.ComponentContext; import org.osgi.service.http.HttpService; +import org.wso2.carbon.device.mgt.input.adapter.extension.InputAdapterExtensionService; import org.wso2.carbon.device.mgt.input.adapter.http.HTTPEventAdapterFactory; import org.wso2.carbon.event.input.adapter.core.InputEventAdapterFactory; import org.wso2.carbon.user.core.service.RealmService; @@ -29,9 +30,19 @@ import org.wso2.carbon.user.core.service.RealmService; * @scr.component name="input.iot.http.AdapterService.component" immediate="true" * @scr.reference name="user.realmservice.default" * interface="org.wso2.carbon.user.core.service.RealmService" cardinality="1..1" - * policy="dynamic" bind="setRealmService" unbind="unsetRealmService" + * policy="dynamic" + * bind="setRealmService" + * unbind="unsetRealmService" * @scr.reference name="http.service" interface="org.osgi.service.http.HttpService" - * cardinality="1..1" policy="dynamic" bind="setHttpService" unbind="unsetHttpService" + * cardinality="1..1" + * policy="dynamic" + * bind="setHttpService" + * unbind="unsetHttpService" + * @scr.reference name="input.extension.service" interface="org.wso2.carbon.device.mgt.input.adapter.extension.InputAdapterExtensionService" + * cardinality="1..1" + * policy="dynamic" + * bind="setInputAdapterExtensionService" + * unbind="unsetInputAdapterExtensionService" */ public class InputAdapterServiceComponent { @@ -67,4 +78,12 @@ public class InputAdapterServiceComponent { InputAdapterServiceDataHolder.registerHTTPService(null); } + protected void setInputAdapterExtensionService(InputAdapterExtensionService inputAdapterExtensionService) { + InputAdapterServiceDataHolder.setInputAdapterExtensionService(inputAdapterExtensionService); + } + + protected void unsetInputAdapterExtensionService(InputAdapterExtensionService inputAdapterExtensionService) { + InputAdapterServiceDataHolder.setInputAdapterExtensionService(null); + } + } diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/internal/InputAdapterServiceDataHolder.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/internal/InputAdapterServiceDataHolder.java index 6f1969e6d..e521f2c3c 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/internal/InputAdapterServiceDataHolder.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/internal/InputAdapterServiceDataHolder.java @@ -15,6 +15,7 @@ package org.wso2.carbon.device.mgt.input.adapter.http.internal; import org.osgi.service.http.HttpService; +import org.wso2.carbon.device.mgt.input.adapter.extension.InputAdapterExtensionService; import org.wso2.carbon.user.core.service.RealmService; /** @@ -24,6 +25,7 @@ public final class InputAdapterServiceDataHolder { private static RealmService realmService; private static HttpService httpService; + private static InputAdapterExtensionService inputAdapterExtensionService; private InputAdapterServiceDataHolder() { } @@ -46,5 +48,12 @@ public final class InputAdapterServiceDataHolder { return httpService; } + public static void setInputAdapterExtensionService(InputAdapterExtensionService inputAdapterExtensionService) { + InputAdapterServiceDataHolder.inputAdapterExtensionService = inputAdapterExtensionService; + } + + public static InputAdapterExtensionService getInputAdapterExtensionService() { + return inputAdapterExtensionService; + } } diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/util/HTTPContentValidator.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/util/HTTPContentValidator.java deleted file mode 100644 index d8085d5b5..000000000 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/util/HTTPContentValidator.java +++ /dev/null @@ -1,99 +0,0 @@ -/* -* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -* -* WSO2 Inc. 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.input.adapter.http.util; - -import com.jayway.jsonpath.JsonPath; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.json.simple.JSONArray; -import org.json.simple.parser.JSONParser; -import org.json.simple.parser.ParseException; -import org.wso2.carbon.device.mgt.input.adapter.extension.ContentInfo; -import org.wso2.carbon.device.mgt.input.adapter.extension.ContentValidator; - -import java.util.List; -import java.util.Map; - -public class HTTPContentValidator implements ContentValidator { - private static final Log log = LogFactory.getLog(HTTPContentValidator.class); - private static String JSON_ARRAY_START_CHAR = "["; - private static String CDMF_SCOPE_PREFIX = "cdmf"; - private static String CDMF_SCOPE_SEPERATOR = "/"; - - @Override - public ContentInfo validate(Object msgPayload, Map dynamicParams) { - String deviceId = (String) dynamicParams.get("deviceId"); - String deviceType = (String) dynamicParams.get("deviceType"); - String msg = (String) msgPayload; - String deviceIdJsonPath = HTTPEventAdapterConstants.DEVICE_ID_JSON_PATH; - boolean status; - if (status = isValidDevice(deviceId, deviceType, dynamicParams)) { - if (msg.startsWith(JSON_ARRAY_START_CHAR)) { - status = processMultipleEvents(msg, deviceId, deviceIdJsonPath); - } else { - status = processSingleEvent(msg, deviceId, deviceIdJsonPath); - } - } - return new ContentInfo(status, msg); - } - - private boolean processSingleEvent(String msg, String deviceIdFromTopic, String deviceIdJsonPath) { - Object res = JsonPath.read(msg, deviceIdJsonPath); - String deviceIdFromContent = (res != null) ? res.toString() : ""; - if (deviceIdFromContent.equals(deviceIdFromTopic)) { - return true; - } - return false; - } - - private boolean processMultipleEvents(String msg, String deviceIdFromTopic, String deviceIdJsonPath) { - try { - JSONParser jsonParser = new JSONParser(); - JSONArray jsonArray = (JSONArray) jsonParser.parse(msg); - boolean status = false; - for (int i = 0; i < jsonArray.size(); i++) { - status = processSingleEvent(jsonArray.get(i).toString(), deviceIdFromTopic, deviceIdJsonPath); - if (!status) { - return status; - } - } - return status; - } catch (ParseException e) { - log.error("Invalid input " + msg, e); - return false; - } - } - - private boolean isValidDevice(String deviceId, String deviceType, Map dynamicParams) { - List scopes = (List) dynamicParams.get(HTTPEventAdapterConstants.SCOPE_TAG); - if (scopes != null) { - for (String scope : scopes) { - if (scope.startsWith(CDMF_SCOPE_PREFIX)) { - String deviceIdInfo[] = scope.split(CDMF_SCOPE_SEPERATOR); - if (deviceIdInfo.length == 3) { - if (deviceId.equals(deviceIdInfo[2]) && deviceType.equals(deviceIdInfo[1])) { - return true; - } - } - } - } - } - return false; - } -} diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/util/HTTPEventAdapterConstants.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/util/HTTPEventAdapterConstants.java index c5d88a975..7fe46450a 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/util/HTTPEventAdapterConstants.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/util/HTTPEventAdapterConstants.java @@ -48,27 +48,17 @@ public final class HTTPEventAdapterConstants { public static final int DEFAULT_HTTP_PORT = 9763; public static final int DEFAULT_HTTPS_PORT = 9443; public static final String MAXIMUM_TOTAL_HTTP_CONNECTION = "maximumTotalHttpConnection"; - public static final String MAXIMUM_TOTAL_HTTP_CONNECTION_HINT = "maximumTotalHttpConnection.hint"; public static final String MAXIMUM_HTTP_CONNECTION_PER_HOST = "maximumHttpConnectionPerHost"; - public static final String MAXIMUM_HTTP_CONNECTION_PER_HOST_HINT = "maximumHttpConnectionPerHost.hint"; - public static final String TOKEN_VALIDATION_ENDPOINT_URL = "keymanagerUrl"; + public static final String TOKEN_VALIDATION_ENDPOINT_URL = "tokenValidationUrl"; public static final String TOKEN_VALIDATION_POST_FIX = "/services/OAuth2TokenValidationService"; public static final String USERNAME = "username"; - public static final String USERNAME_HINT = "username.hint"; public static final String PASSWORD = "password"; - public static final String PASSWORD_HINT = "password.hint"; - public static final String DEFAULT_STRING = "default"; - public static final String MAX_HTTP_CONNECTION = "2"; - public static final String MAX_TOTAL_HTTP_CONNECTION = "100"; public static final String TENANT_DOMAIN_TAG = "tenantDomain"; public static final String USERNAME_TAG = "username"; public static final String SCOPE_TAG = "scopes"; - public static final String PAYLOAD_TAG = "payload"; - public static final String DEVICE_ID_JSON_PATH = "event.metaData.deviceId"; - public static final String ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME = "contentValidator"; - public static final String ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME_HINT = "contentValidator.hint"; + public static final String ADAPTER_CONF_CONTENT_VALIDATOR_TYPE = "contentValidator"; + public static final String ADAPTER_CONF_CONTENT_VALIDATOR_TYPE_HINT = "contentValidator.hint"; public static final String DEFAULT = "default"; - public static final String HTTP_CONTENT_VALIDATION_DEFAULT_PARAMETERS = ""; public static final String ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME = "contentTransformer"; public static final String ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME_HINT = "contentTransformer.hint"; } diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/util/PropertyUtils.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/util/PropertyUtils.java new file mode 100644 index 000000000..d6f442cdd --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/input/adapter/http/util/PropertyUtils.java @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. 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.input.adapter.http.util; + +import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterException; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class PropertyUtils { + + //This method is only used if the mb features are within DAS. + public static String replaceProperty(String urlWithPlaceholders) throws InputEventAdapterException { + String regex = "\\$\\{(.*?)\\}"; + Pattern pattern = Pattern.compile(regex); + Matcher matchPattern = pattern.matcher(urlWithPlaceholders); + while (matchPattern.find()) { + String sysPropertyName = matchPattern.group(1); + String sysPropertyValue = System.getProperty(sysPropertyName); + if (sysPropertyValue != null && !sysPropertyName.isEmpty()) { + urlWithPlaceholders = urlWithPlaceholders.replaceAll("\\$\\{(" + sysPropertyName + ")\\}", sysPropertyValue); + } else { + throw new InputEventAdapterException("System property - " + sysPropertyName + + " is not defined, hence cannot resolve : " + urlWithPlaceholders); + } + } + return urlWithPlaceholders; + } +} diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/resources/org/wso2/carbon/device/mgt/input/adapter/http/i18n/Resources.properties b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/resources/org/wso2/carbon/device/mgt/input/adapter/http/i18n/Resources.properties index d21d20917..0b17e3b53 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/resources/org/wso2/carbon/device/mgt/input/adapter/http/i18n/Resources.properties +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.http/src/main/resources/org/wso2/carbon/device/mgt/input/adapter/http/i18n/Resources.properties @@ -23,6 +23,6 @@ http.usage.tips_mid2=/endpoints/<event_receiver_name>

    For oth http.usage.tips_mid3=/endpoints/t/<tenant_domain>/<event_receiver_name>
      https://localhost: http.usage.tips_postfix=/endpoints/t/<tenant_domain>/<event_receiver_name> contentValidator=contentValidator -contentValidator.hint=Class Name of the content Validation or 'default' to set default class, required to implement (if required) +contentValidator.hint=Type of the content Validation or 'default' to set default impl, required to implement (if required) contentTransformer=contentTransformer -contentTransformer.hint=Class Name of the content transformer or 'default' to set default class, required to implement (if required) \ No newline at end of file +contentTransformer.hint=Type of the content transformer or 'default' to set default type, required to implement (if required) \ No newline at end of file diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/pom.xml b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/pom.xml index 2ca1248e4..75e06262b 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/pom.xml +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/pom.xml @@ -20,7 +20,7 @@ org.wso2.carbon.devicemgt-plugins cdmf-transport-adapters - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../../pom.xml 4.0.0 @@ -32,6 +32,10 @@ http://wso2.org + + commons-codec.wso2 + commons-codec + org.wso2.carbon.analytics-common org.wso2.carbon.event.input.adapter.core @@ -72,6 +76,10 @@ org.wso2.carbon.devicemgt-plugins org.wso2.carbon.device.mgt.input.adapter.extension + + org.wso2.carbon.devicemgt + org.wso2.carbon.identity.jwt.client.extension + @@ -124,9 +132,20 @@ org.apache.http.client.methods;version="${httpclient.version.range}", org.apache.http.impl.client;version="${httpclient.version.range}", org.json.simple.*, - com.jayway.jsonpath.* + com.jayway.jsonpath.*, + org.wso2.carbon.identity.jwt.client.extension.*, + javax.net.ssl, + org.apache.commons.codec.binary, + org.apache.commons.logging, + org.apache.http.entity, + org.osgi.framework, + org.osgi.service.component, + org.osgi.service.http, + org.wso2.carbon.context, + org.wso2.carbon.core, + org.wso2.carbon.device.mgt.input.adapter.extension, + org.wso2.carbon.user.api - * diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/MQTTEventAdapter.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/MQTTEventAdapter.java index a2ddfd446..f6b80dc79 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/MQTTEventAdapter.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/MQTTEventAdapter.java @@ -42,7 +42,6 @@ public class MQTTEventAdapter implements InputEventAdapter { private MQTTAdapterListener mqttAdapterListener; private MQTTBrokerConnectionConfiguration mqttBrokerConnectionConfiguration; - public MQTTEventAdapter(InputEventAdapterConfiguration eventAdapterConfiguration, Map globalProperties) { this.eventAdapterConfiguration = eventAdapterConfiguration; @@ -53,7 +52,6 @@ public class MQTTEventAdapter implements InputEventAdapter { public void init(InputEventAdapterListener eventAdapterListener) throws InputEventAdapterException { this.eventAdapterListener = eventAdapterListener; try { - mqttBrokerConnectionConfiguration = new MQTTBrokerConnectionConfiguration(eventAdapterConfiguration ,globalProperties); mqttAdapterListener = new MQTTAdapterListener(mqttBrokerConnectionConfiguration diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/MQTTEventAdapterFactory.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/MQTTEventAdapterFactory.java index 5212b029d..f5f93b17a 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/MQTTEventAdapterFactory.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/MQTTEventAdapterFactory.java @@ -65,12 +65,12 @@ public class MQTTEventAdapterFactory extends InputEventAdapterFactory { //Content Validator details - Property contentValidator = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME); + Property contentValidator = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_TYPE); contentValidator.setDisplayName( - resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME)); + resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_TYPE)); contentValidator.setRequired(false); contentValidator.setHint( - resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME_HINT)); + resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_TYPE_HINT)); contentValidator.setDefaultValue(MQTTEventAdapterConstants.DEFAULT); propertyList.add(contentValidator); @@ -78,7 +78,7 @@ public class MQTTEventAdapterFactory extends InputEventAdapterFactory { Property userName = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME); userName.setDisplayName( resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME)); - userName.setRequired(true); + userName.setRequired(false); userName.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME_HINT)); propertyList.add(userName); @@ -86,7 +86,7 @@ public class MQTTEventAdapterFactory extends InputEventAdapterFactory { Property password = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_PASSWORD); userName.setDisplayName( resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_PASSWORD)); - userName.setRequired(true); + userName.setRequired(false); userName.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_PASSWORD_HINT)); propertyList.add(password); @@ -108,12 +108,12 @@ public class MQTTEventAdapterFactory extends InputEventAdapterFactory { propertyList.add(clearSession); //Content Transformer details - Property contentTransformer = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME); + Property contentTransformer = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_TYPE); contentTransformer.setDisplayName( - resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME)); + resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_TYPE)); contentTransformer.setRequired(false); contentTransformer.setHint( - resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME_HINT)); + resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_TYPE_HINT)); contentTransformer.setDefaultValue(MQTTEventAdapterConstants.DEFAULT); propertyList.add(contentTransformer); diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/internal/InputAdapterServiceComponent.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/internal/InputAdapterServiceComponent.java index d02b8d356..e281a7dae 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/internal/InputAdapterServiceComponent.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/internal/InputAdapterServiceComponent.java @@ -21,11 +21,23 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.osgi.service.component.ComponentContext; import org.osgi.service.http.HttpService; +import org.wso2.carbon.device.mgt.input.adapter.extension.InputAdapterExtensionService; import org.wso2.carbon.device.mgt.input.adapter.mqtt.MQTTEventAdapterFactory; import org.wso2.carbon.event.input.adapter.core.InputEventAdapterFactory; +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; /** * @scr.component name="input.iot.mqtt.AdapterService.component" immediate="true" + * @scr.reference name="input.extension.service" interface="org.wso2.carbon.device.mgt.input.adapter.extension.InputAdapterExtensionService" + * cardinality="1..1" + * policy="dynamic" + * bind="setInputAdapterExtensionService" + * unbind="unsetInputAdapterExtensionService" + * @scr.reference name="jwt.client.service" interface="org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService" + * cardinality="1..1" + * policy="dynamic" + * bind="setJWTClientManagerService" + * unbind="unsetJWTClientManagerService" */ public class InputAdapterServiceComponent { @@ -52,4 +64,20 @@ public class InputAdapterServiceComponent { InputAdapterServiceDataHolder.registerHTTPService(null); } + protected void setInputAdapterExtensionService(InputAdapterExtensionService inputAdapterExtensionService) { + InputAdapterServiceDataHolder.setInputAdapterExtensionService(inputAdapterExtensionService); + } + + protected void unsetInputAdapterExtensionService(InputAdapterExtensionService inputAdapterExtensionService) { + InputAdapterServiceDataHolder.setInputAdapterExtensionService(null); + } + + protected void setJWTClientManagerService(JWTClientManagerService jwtClientManagerService) { + InputAdapterServiceDataHolder.setJwtClientManagerService(jwtClientManagerService); + } + + protected void unsetJWTClientManagerService(JWTClientManagerService jwtClientManagerService) { + InputAdapterServiceDataHolder.setJwtClientManagerService(null); + } + } diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/internal/InputAdapterServiceDataHolder.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/internal/InputAdapterServiceDataHolder.java index 5335ddfb4..72fdbe245 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/internal/InputAdapterServiceDataHolder.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/internal/InputAdapterServiceDataHolder.java @@ -15,6 +15,8 @@ package org.wso2.carbon.device.mgt.input.adapter.mqtt.internal; import org.osgi.service.http.HttpService; +import org.wso2.carbon.device.mgt.input.adapter.extension.InputAdapterExtensionService; +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; /** * common place to hold some OSGI service references. @@ -22,6 +24,8 @@ import org.osgi.service.http.HttpService; public final class InputAdapterServiceDataHolder { private static HttpService httpService; + private static InputAdapterExtensionService inputAdapterExtensionService; + private static JWTClientManagerService jwtClientManagerService; private InputAdapterServiceDataHolder() { } @@ -35,5 +39,20 @@ public final class InputAdapterServiceDataHolder { return httpService; } + public static void setInputAdapterExtensionService(InputAdapterExtensionService inputAdapterExtensionService) { + InputAdapterServiceDataHolder.inputAdapterExtensionService = inputAdapterExtensionService; + } + public static InputAdapterExtensionService getInputAdapterExtensionService() { + return inputAdapterExtensionService; + } + + public static JWTClientManagerService getJwtClientManagerService() { + return jwtClientManagerService; + } + + public static void setJwtClientManagerService( + JWTClientManagerService jwtClientManagerService) { + InputAdapterServiceDataHolder.jwtClientManagerService = jwtClientManagerService; + } } diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/MQTTAdapterListener.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/MQTTAdapterListener.java index 96546c3ad..dbfc79c9c 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/MQTTAdapterListener.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/MQTTAdapterListener.java @@ -21,14 +21,11 @@ import org.apache.commons.codec.binary.Base64; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; -import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.message.BasicHeader; -import org.apache.http.message.BasicNameValuePair; import org.eclipse.paho.client.mqttv3.*; import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence; import org.json.simple.JSONObject; @@ -39,11 +36,13 @@ import org.wso2.carbon.core.ServerStatus; import org.wso2.carbon.device.mgt.input.adapter.extension.ContentInfo; import org.wso2.carbon.device.mgt.input.adapter.extension.ContentTransformer; import org.wso2.carbon.device.mgt.input.adapter.extension.ContentValidator; -import org.wso2.carbon.device.mgt.input.adapter.extension.DefaultContentTransformer; -import org.wso2.carbon.device.mgt.input.adapter.extension.DefaultContentValidator; +import org.wso2.carbon.device.mgt.input.adapter.mqtt.internal.InputAdapterServiceDataHolder; import org.wso2.carbon.event.input.adapter.core.InputEventAdapterListener; import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterRuntimeException; -import org.wso2.carbon.device.mgt.input.adapter.mqtt.exception.MQTTContentInitializationException; +import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; +import org.wso2.carbon.user.api.UserStoreException; import java.io.IOException; import java.net.MalformedURLException; @@ -51,9 +50,7 @@ import java.net.URL; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; public class MQTTAdapterListener implements MqttCallback, Runnable { @@ -83,7 +80,7 @@ public class MQTTAdapterListener implements MqttCallback, Runnable { this.mqttBrokerConnectionConfiguration = mqttBrokerConnectionConfiguration; this.cleanSession = mqttBrokerConnectionConfiguration.isCleanSession(); int keepAlive = mqttBrokerConnectionConfiguration.getKeepAlive(); - this.topic = topic; + this.topic = PropertyUtils.replaceTenantDomainProperty(topic); this.eventAdapterListener = inputEventAdapterListener; this.tenantId = tenantId; @@ -102,43 +99,23 @@ public class MQTTAdapterListener implements MqttCallback, Runnable { // Set this wrapper as the callback handler mqttClient.setCallback(this); - String contentValidatorClassName = this.mqttBrokerConnectionConfiguration.getContentValidatorClassName(); + String contentValidatorType = this.mqttBrokerConnectionConfiguration.getContentValidatorType(); - if (contentValidatorClassName != null && contentValidatorClassName.equals(MQTTEventAdapterConstants.DEFAULT)) { - contentValidator = new DefaultContentValidator(); - } else if (contentValidatorClassName != null && !contentValidatorClassName.isEmpty()) { - try { - Class contentValidatorClass = Class.forName(contentValidatorClassName) - .asSubclass(ContentValidator.class); - contentValidator = contentValidatorClass.newInstance(); - } catch (ClassNotFoundException e) { - throw new MQTTContentInitializationException( - "Unable to find the class validator: " + contentValidatorClassName, e); - } catch (InstantiationException e) { - throw new MQTTContentInitializationException( - "Unable to create an instance of :" + contentValidatorClassName, e); - } catch (IllegalAccessException e) { - throw new MQTTContentInitializationException("Access of the instance in not allowed.", e); - } + if (contentValidatorType == null || contentValidatorType.equals(MQTTEventAdapterConstants.DEFAULT)) { + contentValidator = InputAdapterServiceDataHolder.getInputAdapterExtensionService() + .getDefaultContentValidator(); + } else { + contentValidator = InputAdapterServiceDataHolder.getInputAdapterExtensionService() + .getContentValidator(contentValidatorType); } - String contentTransformerClassName = this.mqttBrokerConnectionConfiguration.getContentTransformerClassName(); - if (contentTransformerClassName != null && contentTransformerClassName.equals(MQTTEventAdapterConstants.DEFAULT)) { - contentTransformer = new DefaultContentTransformer(); - } else if (contentTransformerClassName != null && !contentTransformerClassName.isEmpty()) { - try { - Class contentTransformerClass = Class.forName(contentTransformerClassName) - .asSubclass(ContentTransformer.class); - contentTransformer = contentTransformerClass.newInstance(); - } catch (ClassNotFoundException e) { - throw new MQTTContentInitializationException( - "Unable to find the class transfoer: " + contentTransformerClassName, e); - } catch (InstantiationException e) { - throw new MQTTContentInitializationException( - "Unable to create an instance of :" + contentTransformerClassName, e); - } catch (IllegalAccessException e) { - throw new MQTTContentInitializationException("Access of the instance in not allowed.", e); - } + String contentTransformerType = this.mqttBrokerConnectionConfiguration.getContentTransformerType(); + if (contentTransformerType == null || contentTransformerType.equals(MQTTEventAdapterConstants.DEFAULT)) { + contentTransformer = InputAdapterServiceDataHolder.getInputAdapterExtensionService() + .getDefaultContentTransformer(); + } else { + contentTransformer = InputAdapterServiceDataHolder.getInputAdapterExtensionService() + .getContentTransformer(contentTransformerType); } } catch (MqttException e) { log.error("Exception occurred while subscribing to MQTT broker at " @@ -165,8 +142,16 @@ public class MQTTAdapterListener implements MqttCallback, Runnable { registrationProfile.setGrantType(MQTTEventAdapterConstants.GRANT_TYPE); registrationProfile.setOwner(username); registrationProfile.setTokenScope(MQTTEventAdapterConstants.TOKEN_SCOPE); - registrationProfile.setClientName(MQTTEventAdapterConstants.APPLICATION_NAME_PREFIX - + mqttBrokerConnectionConfiguration.getAdapterName() + "_" + tenantId); + if (!mqttBrokerConnectionConfiguration.isGlobalCredentailSet()) { + registrationProfile.setClientName(MQTTEventAdapterConstants.APPLICATION_NAME_PREFIX + + mqttBrokerConnectionConfiguration.getAdapterName() + + "_" + tenantId); + registrationProfile.setIsSaasApp(false); + } else { + registrationProfile.setClientName(MQTTEventAdapterConstants.APPLICATION_NAME_PREFIX + + mqttBrokerConnectionConfiguration.getAdapterName()); + registrationProfile.setIsSaasApp(true); + } String jsonString = registrationProfile.toJSON(); StringEntity requestEntity = new StringEntity(jsonString, ContentType.APPLICATION_JSON); postMethod.setEntity(requestEntity); @@ -192,8 +177,10 @@ public class MQTTAdapterListener implements MqttCallback, Runnable { } } catch (MalformedURLException e) { log.error("Invalid dcrUrl : " + dcrUrlString); - } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | IOException e) { - log.error("Failed to create an https connection.", e); + } catch (JWTClientException | UserStoreException e) { + log.error("Failed to create an oauth token with jwt grant type.", e); + } catch (NoSuchAlgorithmException |KeyManagementException |KeyStoreException | IOException e) { + log.error("Failed to create a http connection.", e); } } } @@ -287,34 +274,26 @@ public class MQTTAdapterListener implements MqttCallback, Runnable { } private String getToken(String clientId, String clientSecret) - throws IOException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException, ParseException { - URL tokenEndpoint = new URL(mqttBrokerConnectionConfiguration.getTokenUrl()); - HttpClient httpClient = MQTTUtil.getHttpClient(tokenEndpoint.getProtocol()); - HttpPost postMethod = new HttpPost(tokenEndpoint.toString()); - - List nameValuePairs = new ArrayList<>(); - nameValuePairs.add(new BasicNameValuePair(MQTTEventAdapterConstants.GRANT_TYPE_PARAM_NAME, - MQTTEventAdapterConstants.PASSWORD_GRANT_TYPE)); - nameValuePairs.add(new BasicNameValuePair(MQTTEventAdapterConstants.PASSWORD_GRANT_TYPE_USERNAME, - mqttBrokerConnectionConfiguration.getUsername())); - nameValuePairs.add(new BasicNameValuePair(MQTTEventAdapterConstants.PASSWORD_GRANT_TYPE_PASSWORD, - mqttBrokerConnectionConfiguration.getPassword())); - String scopes = mqttBrokerConnectionConfiguration.getBrokerScopes(); - if (scopes != null && !scopes.isEmpty()) { - nameValuePairs.add(new BasicNameValuePair(MQTTEventAdapterConstants.PASSWORD_GRANT_TYPE_SCOPES, scopes)); - } + throws UserStoreException, JWTClientException { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId, true); + try { + String scopes = mqttBrokerConnectionConfiguration.getBrokerScopes(); + String username = mqttBrokerConnectionConfiguration.getUsername(); + if (mqttBrokerConnectionConfiguration.isGlobalCredentailSet()) { + username = PrivilegedCarbonContext.getThreadLocalCarbonContext() + .getUserRealm().getRealmConfiguration().getAdminUserName() + "@" + PrivilegedCarbonContext + .getThreadLocalCarbonContext().getTenantDomain(true); + } - postMethod.setEntity(new UrlEncodedFormEntity(nameValuePairs)); - postMethod.addHeader("Authorization", "Basic " + getBase64Encode(clientId, clientSecret)); - postMethod.addHeader("Content-Type", "application/x-www-form-urlencoded"); - HttpResponse httpResponse = httpClient.execute(postMethod); - String response = MQTTUtil.getResponseString(httpResponse); - if (log.isDebugEnabled()) { - log.debug(response); + JWTClientManagerService jwtClientManagerService = + InputAdapterServiceDataHolder.getJwtClientManagerService(); + AccessTokenInfo accessTokenInfo = jwtClientManagerService.getJWTClient().getAccessToken( + clientId, clientSecret, username, scopes); + return accessTokenInfo.getAccessToken(); + } finally { + PrivilegedCarbonContext.endTenantFlow(); } - JSONParser jsonParser = new JSONParser(); - JSONObject jsonObject = (JSONObject) jsonParser.parse(response); - return (String) jsonObject.get(MQTTEventAdapterConstants.ACCESS_TOKEN_GRANT_TYPE_PARAM_NAME); } private String getBase64Encode(String key, String value) { diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/MQTTBrokerConnectionConfiguration.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/MQTTBrokerConnectionConfiguration.java index 59ef8a3b4..3685c245f 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/MQTTBrokerConnectionConfiguration.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/MQTTBrokerConnectionConfiguration.java @@ -34,10 +34,10 @@ public class MQTTBrokerConnectionConfiguration { private int keepAlive; private String brokerUrl; private String dcrUrl; - private String tokenUrl; - private String contentValidatorClassName; - private String contentTransformerClassName; + private String contentValidatorType; + private String contentTransformerType; private String adapterName; + private boolean globalCredentailSet; public String getBrokerScopes() { return brokerScopes; @@ -67,16 +67,16 @@ public class MQTTBrokerConnectionConfiguration { return keepAlive; } - public String getContentValidatorClassName() { - return contentValidatorClassName; + public String getContentValidatorType() { + return contentValidatorType; } - public String getContentTransformerClassName() { - return contentTransformerClassName; + public String getContentTransformerType() { + return contentTransformerType; } - public String getTokenUrl() { - return tokenUrl; + public boolean isGlobalCredentailSet() { + return globalCredentailSet; } public String getAdapterName() { @@ -89,6 +89,11 @@ public class MQTTBrokerConnectionConfiguration { adapterName = eventAdapterConfiguration.getName(); this.username = eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME); this.password = eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_PASSWORD); + if ((username == null || username.isEmpty()) && (password == null || password.isEmpty())) { + username = globalProperties.get(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME); + password = globalProperties.get(MQTTEventAdapterConstants.ADAPTER_CONF_PASSWORD); + globalCredentailSet = true; + } this.brokerScopes = eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_SCOPES); if (brokerScopes == null) { this.brokerScopes = MQTTEventAdapterConstants.EMPTY_STRING; @@ -100,10 +105,8 @@ public class MQTTBrokerConnectionConfiguration { this.brokerUrl = PropertyUtils.replaceMqttProperty(url); this.dcrUrl = PropertyUtils .replaceMqttProperty(globalProperties.get(MQTTEventAdapterConstants.ADAPTER_CONF_DCR_URL)); - this.tokenUrl = PropertyUtils - .replaceMqttProperty(globalProperties.get(MQTTEventAdapterConstants.ADAPTER_CONF_TOKEN_URL)); - this.contentValidatorClassName = eventAdapterConfiguration.getProperties() - .get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME); + this.contentValidatorType = eventAdapterConfiguration.getProperties() + .get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_TYPE); this.cleanSession = Boolean.parseBoolean(eventAdapterConfiguration.getProperties() .get(MQTTEventAdapterConstants.ADAPTER_CONF_CLEAN_SESSION)); //If global properties are available those will be assigned else constant values will be assigned @@ -112,7 +115,7 @@ public class MQTTBrokerConnectionConfiguration { } else { keepAlive = MQTTEventAdapterConstants.ADAPTER_CONF_DEFAULT_KEEP_ALIVE; } - this.contentTransformerClassName = eventAdapterConfiguration.getProperties() - .get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME); + this.contentTransformerType = eventAdapterConfiguration.getProperties() + .get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_TYPE); } } diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/MQTTEventAdapterConstants.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/MQTTEventAdapterConstants.java index f21abd29b..dc0e45413 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/MQTTEventAdapterConstants.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/MQTTEventAdapterConstants.java @@ -35,10 +35,10 @@ public class MQTTEventAdapterConstants { public static final String ADAPTER_CONF_DCR_URL = "dcrUrl"; public static final String ADAPTER_CONF_TOKEN_URL = "tokenUrl"; public static final String ADAPTER_CONF_DCR_URL_HINT = "dcrUrl.hint"; - public static final String ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME = "contentValidator"; - public static final String ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME_HINT = "contentValidator.hint"; - public static final String ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME = "contentTransformer"; - public static final String ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME_HINT = "contentTransformer.hint"; + public static final String ADAPTER_CONF_CONTENT_VALIDATOR_TYPE = "contentValidator"; + public static final String ADAPTER_CONF_CONTENT_VALIDATOR_TYPE_HINT = "contentValidator.hint"; + public static final String ADAPTER_CONF_CONTENT_TRANSFORMER_TYPE = "contentTransformer"; + public static final String ADAPTER_CONF_CONTENT_TRANSFORMER_TYPE_HINT = "contentTransformer.hint"; public static final String ADAPTER_MESSAGE_TOPIC = "topic"; public static final String ADAPTER_MESSAGE_TOPIC_HINT = "topic.hint"; public static final String ADAPTER_CONF_CLIENTID = "clientId"; @@ -53,7 +53,7 @@ public class MQTTEventAdapterConstants { public static final String EMPTY_STRING = ""; public static final String GRANT_TYPE_PARAM_NAME = "grant_type"; - public static final String GRANT_TYPE = "password refresh_token"; + public static final String GRANT_TYPE = "password refresh_token urn:ietf:params:oauth:grant-type:jwt-bearer"; public static final String TOKEN_SCOPE = "production"; public static final String APPLICATION_NAME_PREFIX = "InputAdapter_"; public static final String CLIENT_ID = "clientId"; @@ -63,15 +63,7 @@ public class MQTTEventAdapterConstants { public static final String MQTT_CONTENT_VALIDATION_DEFAULT_PARAMETERS = ""; public static final String TOPIC = "topic"; public static final String PAYLOAD = "payload"; - public static final String DEVICE_ID_JSON_PATH = "event.metaData.deviceId"; - public static final String DEVICE_TYPE_JSON_PATH = "event.metaData.deviceId"; - public static final int DEVICE_ID_TOPIC_HIERARCHY_INDEX = 2; public static final String AUTHORIZATION_HEADER_NAME = "Authorization"; public static final String AUTHORIZATION_HEADER_VALUE_PREFIX = "Basic "; - public static final String PASSWORD_GRANT_TYPE = "password"; - public static final String PASSWORD_GRANT_TYPE_USERNAME = "username"; - public static final String PASSWORD_GRANT_TYPE_PASSWORD = "password"; - public static final String PASSWORD_GRANT_TYPE_SCOPES = "scopes"; - public static final String ACCESS_TOKEN_GRANT_TYPE_PARAM_NAME = "access_token"; } diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/PropertyUtils.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/PropertyUtils.java index 91a512b79..682a292f7 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/PropertyUtils.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/PropertyUtils.java @@ -18,12 +18,14 @@ package org.wso2.carbon.device.mgt.input.adapter.mqtt.util; +import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterException; import java.util.regex.Matcher; import java.util.regex.Pattern; class PropertyUtils { + private static final String TENANT_DOMAIN_PROPERTY = "\\$\\{tenant-domain\\}"; //This method is only used if the mb features are within DAS. static String replaceMqttProperty(String urlWithPlaceholders) throws InputEventAdapterException { @@ -42,4 +44,10 @@ class PropertyUtils { } return urlWithPlaceholders; } + + public static String replaceTenantDomainProperty (String urlWithPlaceholders) { + urlWithPlaceholders = urlWithPlaceholders.replaceAll(TENANT_DOMAIN_PROPERTY, PrivilegedCarbonContext + .getThreadLocalCarbonContext().getTenantDomain(true)); + return urlWithPlaceholders; + } } diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/RegistrationProfile.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/RegistrationProfile.java index f5445f170..fddc8e534 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/RegistrationProfile.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/RegistrationProfile.java @@ -12,6 +12,7 @@ public class RegistrationProfile { private String owner; private String grantType; private String applicationType; + private boolean isSaasApp; private static final String TAG = RegistrationProfile.class.getSimpleName(); @@ -63,11 +64,19 @@ public class RegistrationProfile { this.applicationType = applicationType; } - public String toJSON() { + public boolean isSaasApp() { + return isSaasApp; + } + + public void setIsSaasApp(boolean isSaasApp) { + this.isSaasApp = isSaasApp; + } + + public String toJSON() { String jsonString = "{\"callbackUrl\": \"" + callbackUrl + "\",\"clientName\": \"" + clientName + "\", \"tokenScope\": " + "\"" + tokenScope + "\", \"owner\": \"" + owner + "\"," + "\"grantType\": \"" + grantType + - "\", \"saasApp\" :false }\n"; + "\", \"saasApp\" :" + isSaasApp + " }\n"; return jsonString; } } \ No newline at end of file diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/resources/org/wso2/carbon/device/mgt/input/adapter/mqtt/i18n/Resources.properties b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/resources/org/wso2/carbon/device/mgt/input/adapter/mqtt/i18n/Resources.properties index 38cfcf7c6..aee8d9a4c 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/resources/org/wso2/carbon/device/mgt/input/adapter/mqtt/i18n/Resources.properties +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/resources/org/wso2/carbon/device/mgt/input/adapter/mqtt/i18n/Resources.properties @@ -27,14 +27,12 @@ password=Password password.hint=Password of the user for the broker (if required) scopes=Scopes scopes.hint=Scopes required to connect to broker (if required) -dcrUrl=dcrUrl -dcrUrl.hint=dynamic client registration endpoint URL to create application (if required) eg: https://localhost:9443/dynamic-client-web/register contentValidator=contentValidation -contentValidator.hint=Class Name of the content Validation or 'default' to set default class, required to implement (if required) +contentValidator.hint=Type of the content Validation or 'default' to set default type, required to implement (if required) url.hint=MQTT broker url tcp://localhost:1883 cleanSession=Clean Session cleanSession.hint=Persist topic subscriptions and ack positions across client sessions keepAlive=Keep Alive (In seconds) events.duplicated.in.cluster=Is events duplicated in cluster contentTransformer=contentTransformer -contentTransformer.hint=Class Name of the content transformer or 'default' to set default class, required to implement (if required) \ No newline at end of file +contentTransformer.hint=Type of the content transformer or 'default' to set default type, required to implement (if required) \ No newline at end of file diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.xmpp/pom.xml b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.xmpp/pom.xml index b125b2459..1f1b6d602 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.xmpp/pom.xml +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.xmpp/pom.xml @@ -20,7 +20,7 @@ org.wso2.carbon.devicemgt-plugins cdmf-transport-adapters - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../../pom.xml 4.0.0 @@ -116,9 +116,16 @@ org.jivesoftware.smack.*, org.apache.log4j, org.wso2.carbon.base, - org.wso2.carbon.core.util + org.wso2.carbon.core.util, + org.apache.commons.logging, + org.osgi.framework, + org.osgi.service.component, + org.osgi.service.http, + org.wso2.carbon.context, + org.wso2.carbon.core, + org.wso2.carbon.device.mgt.input.adapter.extension, + org.wso2.carbon.user.core.service - * diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/input/adapter/xmpp/internal/InputAdapterServiceComponent.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/input/adapter/xmpp/internal/InputAdapterServiceComponent.java index 32db2049b..4099c23f3 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/input/adapter/xmpp/internal/InputAdapterServiceComponent.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/input/adapter/xmpp/internal/InputAdapterServiceComponent.java @@ -21,6 +21,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.osgi.service.component.ComponentContext; import org.osgi.service.http.HttpService; +import org.wso2.carbon.device.mgt.input.adapter.extension.InputAdapterExtensionService; import org.wso2.carbon.device.mgt.input.adapter.xmpp.XMPPEventAdapterFactory; import org.wso2.carbon.event.input.adapter.core.InputEventAdapterFactory; import org.wso2.carbon.user.core.service.RealmService; @@ -30,6 +31,11 @@ import org.wso2.carbon.user.core.service.RealmService; * @scr.reference name="user.realmservice.default" * interface="org.wso2.carbon.user.core.service.RealmService" cardinality="1..1" * policy="dynamic" bind="setRealmService" unbind="unsetRealmService" + * @scr.reference name="input.extension.service" interface="org.wso2.carbon.device.mgt.input.adapter.extension.InputAdapterExtensionService" + * cardinality="1..1" + * policy="dynamic" + * bind="setInputAdapterExtensionService" + * unbind="unsetInputAdapterExtensionService" */ public class InputAdapterServiceComponent { @@ -64,4 +70,12 @@ public class InputAdapterServiceComponent { InputAdapterServiceDataHolder.registerHTTPService(null); } + protected void setInputAdapterExtensionService(InputAdapterExtensionService inputAdapterExtensionService) { + InputAdapterServiceDataHolder.setInputAdapterExtensionService(inputAdapterExtensionService); + } + + protected void unsetInputAdapterExtensionService(InputAdapterExtensionService inputAdapterExtensionService) { + InputAdapterServiceDataHolder.setInputAdapterExtensionService(null); + } + } diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/input/adapter/xmpp/internal/InputAdapterServiceDataHolder.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/input/adapter/xmpp/internal/InputAdapterServiceDataHolder.java index 38296aea8..f2c92c898 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/input/adapter/xmpp/internal/InputAdapterServiceDataHolder.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/input/adapter/xmpp/internal/InputAdapterServiceDataHolder.java @@ -15,6 +15,7 @@ package org.wso2.carbon.device.mgt.input.adapter.xmpp.internal; import org.osgi.service.http.HttpService; +import org.wso2.carbon.device.mgt.input.adapter.extension.InputAdapterExtensionService; import org.wso2.carbon.user.core.service.RealmService; /** @@ -24,6 +25,7 @@ public final class InputAdapterServiceDataHolder { private static RealmService realmService; private static HttpService httpService; + private static InputAdapterExtensionService inputAdapterExtensionService; private InputAdapterServiceDataHolder() { } @@ -46,5 +48,12 @@ public final class InputAdapterServiceDataHolder { return httpService; } + public static void setInputAdapterExtensionService(InputAdapterExtensionService inputAdapterExtensionService) { + InputAdapterServiceDataHolder.inputAdapterExtensionService = inputAdapterExtensionService; + } + + public static InputAdapterExtensionService getInputAdapterExtensionService() { + return inputAdapterExtensionService; + } } diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/input/adapter/xmpp/util/XMPPAdapterListener.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/input/adapter/xmpp/util/XMPPAdapterListener.java index 2dd10098a..3203ba586 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/input/adapter/xmpp/util/XMPPAdapterListener.java +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/input/adapter/xmpp/util/XMPPAdapterListener.java @@ -21,7 +21,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jivesoftware.smack.ConnectionConfiguration; import org.jivesoftware.smack.PacketListener; -import org.jivesoftware.smack.ReconnectionManager; import org.jivesoftware.smack.SmackConfiguration; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; @@ -36,9 +35,10 @@ import org.wso2.carbon.core.ServerStatus; import org.wso2.carbon.device.mgt.input.adapter.extension.ContentInfo; import org.wso2.carbon.device.mgt.input.adapter.extension.ContentTransformer; import org.wso2.carbon.device.mgt.input.adapter.extension.ContentValidator; -import org.wso2.carbon.device.mgt.input.adapter.extension.DefaultContentTransformer; -import org.wso2.carbon.device.mgt.input.adapter.extension.DefaultContentValidator; +import org.wso2.carbon.device.mgt.input.adapter.extension.transformer.DefaultContentTransformer; +import org.wso2.carbon.device.mgt.input.adapter.extension.validator.DefaultContentValidator; import org.wso2.carbon.device.mgt.input.adapter.xmpp.exception.XMPPContentInitializationException; +import org.wso2.carbon.device.mgt.input.adapter.xmpp.internal.InputAdapterServiceDataHolder; import org.wso2.carbon.event.input.adapter.core.InputEventAdapterListener; import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterRuntimeException; import java.util.HashMap; @@ -58,55 +58,27 @@ public class XMPPAdapterListener implements Runnable { private InputEventAdapterListener eventAdapterListener = null; - public XMPPAdapterListener(XMPPServerConnectionConfiguration xmppServerConnectionConfiguration, InputEventAdapterListener inputEventAdapterListener, int tenantId) { this.xmppServerConnectionConfiguration = xmppServerConnectionConfiguration; this.eventAdapterListener = inputEventAdapterListener; this.tenantId = tenantId; - try { - String contentValidatorClassName = this.xmppServerConnectionConfiguration.getContentValidatorClassName(); - if (contentValidatorClassName != null && contentValidatorClassName.equals(XMPPEventAdapterConstants.DEFAULT)) { - contentValidator = new DefaultContentValidator(); - } else if (contentValidatorClassName != null && !contentValidatorClassName.isEmpty()) { - try { - Class contentValidatorClass = Class.forName(contentValidatorClassName) - .asSubclass(ContentValidator.class); - contentValidator = contentValidatorClass.newInstance(); - } catch (ClassNotFoundException e) { - throw new XMPPContentInitializationException( - "Unable to find the class validator: " + contentValidatorClassName, e); - } catch (InstantiationException e) { - throw new XMPPContentInitializationException( - "Unable to create an instance of :" + contentValidatorClassName, e); - } catch (IllegalAccessException e) { - throw new XMPPContentInitializationException("Access of the instance in not allowed.", e); - } - } + String contentValidatorType = this.xmppServerConnectionConfiguration.getContentValidatorClassName(); + if (contentValidatorType == null || contentValidatorType.equals(XMPPEventAdapterConstants.DEFAULT)) { + contentValidator = InputAdapterServiceDataHolder.getInputAdapterExtensionService().getDefaultContentValidator(); + } else { + contentValidator = InputAdapterServiceDataHolder.getInputAdapterExtensionService() + .getContentValidator(contentValidatorType); + } - String contentTransformerClassName = this.xmppServerConnectionConfiguration.getContentTransformerClassName(); - if (contentTransformerClassName != null && contentTransformerClassName.equals(XMPPEventAdapterConstants.DEFAULT)) { - contentTransformer = new DefaultContentTransformer(); - } else if (contentTransformerClassName != null && !contentTransformerClassName.isEmpty()) { - try { - Class contentTransformerClass = Class.forName(contentTransformerClassName) - .asSubclass(ContentTransformer.class); - contentTransformer = contentTransformerClass.newInstance(); - } catch (ClassNotFoundException e) { - throw new XMPPContentInitializationException( - "Unable to find the class transformer: " + contentTransformerClassName, e); - } catch (InstantiationException e) { - throw new XMPPContentInitializationException( - "Unable to create an instance of :" + contentTransformerClassName, e); - } catch (IllegalAccessException e) { - throw new XMPPContentInitializationException("Access of the instance in not allowed.", e); - } - } - } catch (Throwable e) { - log.error("Exception occurred while subscribing to MQTT broker at " - + xmppServerConnectionConfiguration.getHost()); - throw new InputEventAdapterRuntimeException(e); + String contentTransformerType = this.xmppServerConnectionConfiguration.getContentTransformerClassName(); + if (contentTransformer == null || contentTransformerType.equals(XMPPEventAdapterConstants.DEFAULT)) { + this.contentTransformer = InputAdapterServiceDataHolder.getInputAdapterExtensionService() + .getDefaultContentTransformer(); + } else { + this.contentTransformer = InputAdapterServiceDataHolder.getInputAdapterExtensionService() + .getContentTransformer(contentTransformerType); } } diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.xmpp/src/main/resources/org/wso2/carbon/device/mgt/input/adapter/xmpp/i18n/Resources.properties b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.xmpp/src/main/resources/org/wso2/carbon/device/mgt/input/adapter/xmpp/i18n/Resources.properties index ac6b7f1e1..7c63ed55d 100644 --- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.xmpp/src/main/resources/org/wso2/carbon/device/mgt/input/adapter/xmpp/i18n/Resources.properties +++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.xmpp/src/main/resources/org/wso2/carbon/device/mgt/input/adapter/xmpp/i18n/Resources.properties @@ -29,8 +29,8 @@ timeoutInterval.hint=used by listeners to the server and for reconnection schedu resource=Resource resource.hint=specific to the XMPP-Account to which the login is made to. contentValidator=contentValidation -contentValidator.hint=Class Name of the content Validation or 'default' to set default class, required to implement (if required) +contentValidator.hint=Type of the content Validation or 'default' to set default type, required to implement (if required) jid=jid jid.hint=JID - XMPP Account Name. contentTransformer=contentTransformer -contentTransformer.hint=Class Name of the content transformer or 'default' to set default class, required to implement (if required) \ No newline at end of file +contentTransformer.hint=Type of the content transformer or 'default' to set default type, required to implement (if required) \ No newline at end of file diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/pom.xml b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/pom.xml index 8c29a6cae..c35581e67 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/pom.xml +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/pom.xml @@ -20,7 +20,7 @@ org.wso2.carbon.devicemgt-plugins cdmf-transport-adapters - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../../pom.xml 4.0.0 @@ -33,6 +33,10 @@ http://wso2.org + + commons-codec.wso2 + commons-codec + org.wso2.carbon.analytics-common org.wso2.carbon.event.output.adapter.core @@ -61,6 +65,10 @@ com.googlecode.json-simple.wso2 json-simple + + org.wso2.carbon.devicemgt + org.wso2.carbon.identity.jwt.client.extension + @@ -121,7 +129,9 @@ org.apache.commons.codec.binary, org.apache.http.client.entity, org.apache.http.message, - org.apache.commons.ssl + org.apache.commons.ssl, + org.wso2.carbon.identity.jwt.client.extension.*, + org.wso2.carbon.user.api diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/MQTTEventAdapter.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/MQTTEventAdapter.java index a87fddf58..fbc9c015d 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/MQTTEventAdapter.java +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/MQTTEventAdapter.java @@ -122,7 +122,7 @@ public class MQTTEventAdapter implements OutputEventAdapter { String clientId = eventAdapterConfiguration.getStaticProperties().get( MQTTEventAdapterConstants.ADAPTER_CONF_CLIENTID); qos = eventAdapterConfiguration.getStaticProperties().get(MQTTEventAdapterConstants.ADAPTER_MESSAGE_QOS); - mqttAdapterPublisher = new MQTTAdapterPublisher(mqttBrokerConnectionConfiguration, clientId); + mqttAdapterPublisher = new MQTTAdapterPublisher(mqttBrokerConnectionConfiguration, clientId, tenantId); } @Override diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/MQTTEventAdapterFactory.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/MQTTEventAdapterFactory.java index 9275ec20d..1c8cd43de 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/MQTTEventAdapterFactory.java +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/MQTTEventAdapterFactory.java @@ -56,19 +56,20 @@ public class MQTTEventAdapterFactory extends OutputEventAdapterFactory { //Broker Username Property userName = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME); userName.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME)); - userName.setRequired(true); + userName.setRequired(false); userName.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME_HINT)); //Broker Password Property password = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_PASSWORD); password.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_PASSWORD)); - password.setRequired(true); + password.setRequired(false); password.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_PASSWORD_HINT)); //Broker Connection Scopes Property scopes = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_SCOPES); scopes.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_SCOPES)); - scopes.setRequired(true); + scopes.setRequired(false); + scopes.setDefaultValue("default"); scopes.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_SCOPES_HINT)); // set clientId diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/internal/MQTTEventAdapterServiceComponent.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/internal/MQTTEventAdapterServiceComponent.java index 80784a4ce..d7ff9d9ed 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/internal/MQTTEventAdapterServiceComponent.java +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/internal/MQTTEventAdapterServiceComponent.java @@ -22,10 +22,15 @@ import org.apache.commons.logging.LogFactory; import org.osgi.service.component.ComponentContext; import org.wso2.carbon.device.mgt.output.adapter.mqtt.MQTTEventAdapterFactory; import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterFactory; - +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; /** * @scr.component component.name="output.Mqtt.AdapterService.component" immediate="true" + * @scr.reference name="jwt.client.service" interface="org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService" + * cardinality="1..1" + * policy="dynamic" + * bind="setJWTClientManagerService" + * unbind="unsetJWTClientManagerService" */ public class MQTTEventAdapterServiceComponent { @@ -48,4 +53,12 @@ public class MQTTEventAdapterServiceComponent { } } + protected void setJWTClientManagerService(JWTClientManagerService jwtClientManagerService) { + OutputAdapterServiceDataHolder.setJwtClientManagerService(jwtClientManagerService); + } + + protected void unsetJWTClientManagerService(JWTClientManagerService jwtClientManagerService) { + OutputAdapterServiceDataHolder.setJwtClientManagerService(null); + } + } diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/internal/OutputAdapterServiceDataHolder.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/internal/OutputAdapterServiceDataHolder.java new file mode 100644 index 000000000..9cda29113 --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/internal/OutputAdapterServiceDataHolder.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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 org.wso2.carbon.device.mgt.output.adapter.mqtt.internal; + +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; + +/** + * common place to hold some OSGI service references. + */ +public final class OutputAdapterServiceDataHolder { + + private static JWTClientManagerService jwtClientManagerService; + + public static JWTClientManagerService getJwtClientManagerService() { + return jwtClientManagerService; + } + + public static void setJwtClientManagerService( + JWTClientManagerService jwtClientManagerService) { + OutputAdapterServiceDataHolder.jwtClientManagerService = jwtClientManagerService; + } +} diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/util/MQTTAdapterPublisher.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/util/MQTTAdapterPublisher.java index 79188e840..38f078ff7 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/util/MQTTAdapterPublisher.java +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/util/MQTTAdapterPublisher.java @@ -21,14 +21,11 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.ssl.Base64; import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; -import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.message.BasicHeader; -import org.apache.http.message.BasicNameValuePair; import org.eclipse.paho.client.mqttv3.MqttClient; import org.eclipse.paho.client.mqttv3.MqttConnectOptions; import org.eclipse.paho.client.mqttv3.MqttException; @@ -38,9 +35,14 @@ import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.output.adapter.mqtt.internal.OutputAdapterServiceDataHolder; import org.wso2.carbon.event.output.adapter.core.exception.ConnectionUnavailableException; import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException; import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterRuntimeException; +import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; +import org.wso2.carbon.user.api.UserStoreException; import java.io.IOException; import java.net.MalformedURLException; @@ -48,8 +50,6 @@ import java.net.URL; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.List; /** * MQTT publisher related configuration initialization and publishing capabilties are implemented here. @@ -60,8 +60,11 @@ public class MQTTAdapterPublisher { private MqttClient mqttClient; private MQTTBrokerConnectionConfiguration mqttBrokerConnectionConfiguration; String clientId; + int tenantId; - public MQTTAdapterPublisher(MQTTBrokerConnectionConfiguration mqttBrokerConnectionConfiguration, String clientId) { + public MQTTAdapterPublisher(MQTTBrokerConnectionConfiguration mqttBrokerConnectionConfiguration, String clientId + , int tenantId) { + this.tenantId = tenantId; if (clientId == null || clientId.trim().isEmpty()) { this.clientId = MqttClient.generateClientId(); } @@ -146,7 +149,6 @@ public class MQTTAdapterPublisher { String password = this.mqttBrokerConnectionConfiguration.getPassword(); String dcrUrlString = this.mqttBrokerConnectionConfiguration.getDcrUrl(); - int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); if (dcrUrlString != null && !dcrUrlString.isEmpty()) { try { URL dcrUrl = new URL(dcrUrlString); @@ -157,8 +159,16 @@ public class MQTTAdapterPublisher { registrationProfile.setGrantType(MQTTEventAdapterConstants.GRANT_TYPE); registrationProfile.setOwner(username); registrationProfile.setTokenScope(MQTTEventAdapterConstants.TOKEN_SCOPE); - registrationProfile.setClientName(MQTTEventAdapterConstants.APPLICATION_NAME_PREFIX - + mqttBrokerConnectionConfiguration.getAdapterName() + "_" + tenantId); + if (!mqttBrokerConnectionConfiguration.isGlobalCredentailSet()) { + registrationProfile.setClientName(MQTTEventAdapterConstants.APPLICATION_NAME_PREFIX + + mqttBrokerConnectionConfiguration.getAdapterName() + + "_" + tenantId); + registrationProfile.setIsSaasApp(false); + } else { + registrationProfile.setClientName(MQTTEventAdapterConstants.APPLICATION_NAME_PREFIX + + mqttBrokerConnectionConfiguration.getAdapterName()); + registrationProfile.setIsSaasApp(true); + } String jsonString = registrationProfile.toJSON(); StringEntity requestEntity = new StringEntity(jsonString, ContentType.APPLICATION_JSON); postMethod.setEntity(requestEntity); @@ -186,40 +196,34 @@ public class MQTTAdapterPublisher { throw new OutputEventAdapterRuntimeException("Invalid dcrUrl : " + dcrUrlString); } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | IOException e) { throw new OutputEventAdapterRuntimeException("Failed to create an https connection.", e); + } catch (JWTClientException | UserStoreException e) { + log.error("Failed to create an oauth token with jwt grant type.", e); } } throw new OutputEventAdapterRuntimeException("Invalid configuration for mqtt publisher"); } private String getToken(String clientId, String clientSecret) - throws IOException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException, ParseException { - URL tokenEndpoint = new URL(mqttBrokerConnectionConfiguration.getTokenUrl()); - HttpClient httpClient = MQTTUtil.getHttpClient(tokenEndpoint.getProtocol()); - HttpPost postMethod = new HttpPost(tokenEndpoint.toString()); - - List nameValuePairs = new ArrayList<>(); - nameValuePairs.add(new BasicNameValuePair(MQTTEventAdapterConstants.GRANT_TYPE_PARAM_NAME, - MQTTEventAdapterConstants.PASSWORD_GRANT_TYPE)); - nameValuePairs.add(new BasicNameValuePair(MQTTEventAdapterConstants.PASSWORD_GRANT_TYPE_USERNAME, - mqttBrokerConnectionConfiguration.getUsername())); - nameValuePairs.add(new BasicNameValuePair(MQTTEventAdapterConstants.PASSWORD_GRANT_TYPE_PASSWORD, - mqttBrokerConnectionConfiguration.getPassword())); - String scopes = mqttBrokerConnectionConfiguration.getScopes(); - if (scopes != null && !scopes.isEmpty()) { - nameValuePairs.add(new BasicNameValuePair(MQTTEventAdapterConstants.PASSWORD_GRANT_TYPE_SCOPES, scopes)); - } + throws UserStoreException, JWTClientException { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId, true); + try { + String scopes = mqttBrokerConnectionConfiguration.getScopes(); + String username = mqttBrokerConnectionConfiguration.getUsername(); + if (mqttBrokerConnectionConfiguration.isGlobalCredentailSet()) { + username = PrivilegedCarbonContext.getThreadLocalCarbonContext() + .getUserRealm().getRealmConfiguration().getAdminUserName() + "@" + PrivilegedCarbonContext + .getThreadLocalCarbonContext().getTenantDomain(true); + } - postMethod.setEntity(new UrlEncodedFormEntity(nameValuePairs)); - postMethod.addHeader("Authorization", "Basic " + getBase64Encode(clientId, clientSecret)); - postMethod.addHeader("Content-Type", "application/x-www-form-urlencoded"); - HttpResponse httpResponse = httpClient.execute(postMethod); - String response = MQTTUtil.getResponseString(httpResponse); - if (log.isDebugEnabled()) { - log.debug(response); + JWTClientManagerService jwtClientManagerService = + OutputAdapterServiceDataHolder.getJwtClientManagerService(); + AccessTokenInfo accessTokenInfo = jwtClientManagerService.getJWTClient().getAccessToken( + clientId, clientSecret, username, scopes); + return accessTokenInfo.getAccessToken(); + } finally { + PrivilegedCarbonContext.endTenantFlow(); } - JSONParser jsonParser = new JSONParser(); - JSONObject jsonObject = (JSONObject) jsonParser.parse(response); - return (String) jsonObject.get(MQTTEventAdapterConstants.ACCESS_TOKEN_GRANT_TYPE_PARAM_NAME); } private String getBase64Encode(String key, String value) { diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/util/MQTTBrokerConnectionConfiguration.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/util/MQTTBrokerConnectionConfiguration.java index b88d9d18b..2bbd394ab 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/util/MQTTBrokerConnectionConfiguration.java +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/util/MQTTBrokerConnectionConfiguration.java @@ -33,6 +33,8 @@ public class MQTTBrokerConnectionConfiguration { private String tokenUrl; private boolean cleanSession = true; private int keepAlive; + private boolean globalCredentailSet; + public String getTokenUrl() { return tokenUrl; } @@ -69,11 +71,20 @@ public class MQTTBrokerConnectionConfiguration { return adapterName; } + public boolean isGlobalCredentailSet() { + return globalCredentailSet; + } + public MQTTBrokerConnectionConfiguration(OutputEventAdapterConfiguration eventAdapterConfiguration, Map globalProperties) { adapterName = eventAdapterConfiguration.getName(); this.username = eventAdapterConfiguration.getStaticProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME); this.password = eventAdapterConfiguration.getStaticProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_PASSWORD); + if ((username == null || username.isEmpty()) && (password == null || password.isEmpty())) { + username = globalProperties.get(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME); + password = globalProperties.get(MQTTEventAdapterConstants.ADAPTER_CONF_PASSWORD); + globalCredentailSet = true; + } String url = eventAdapterConfiguration .getStaticProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_URL); if (url == null || url.isEmpty()) { url = globalProperties.get(MQTTEventAdapterConstants.ADAPTER_CONF_URL); diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/util/MQTTEventAdapterConstants.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/util/MQTTEventAdapterConstants.java index 732af141c..1f2bbdd38 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/util/MQTTEventAdapterConstants.java +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/util/MQTTEventAdapterConstants.java @@ -58,7 +58,7 @@ public final class MQTTEventAdapterConstants { public static final String DEFAULT_CALLBACK = ""; public static final String DEFAULT_PASSWORD = ""; - public static final String GRANT_TYPE = "password"; + public static final String GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer"; public static final String TOKEN_SCOPE = "production"; public static final String APPLICATION_NAME_PREFIX = "OutputAdapter_"; public static final String CLIENT_ID = "clientId"; diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/util/PropertyUtils.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/util/PropertyUtils.java index deda48085..f77279934 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/util/PropertyUtils.java +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/util/PropertyUtils.java @@ -21,10 +21,10 @@ package org.wso2.carbon.device.mgt.output.adapter.mqtt.util; import java.util.regex.Matcher; import java.util.regex.Pattern; -class PropertyUtils { +public class PropertyUtils { //This method is only used if the mb features are within DAS. - static String replaceMqttProperty(String urlWithPlaceholders) { + public static String replaceMqttProperty(String urlWithPlaceholders) { String regex = "\\$\\{(.*?)\\}"; Pattern pattern = Pattern.compile(regex); Matcher matchPattern = pattern.matcher(urlWithPlaceholders); diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/util/RegistrationProfile.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/util/RegistrationProfile.java index 0a4d93125..ef9249bd6 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/util/RegistrationProfile.java +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/output/adapter/mqtt/util/RegistrationProfile.java @@ -12,6 +12,7 @@ public class RegistrationProfile { private String owner; private String grantType; private String applicationType; + private boolean isSaasApp; private static final String TAG = RegistrationProfile.class.getSimpleName(); @@ -63,11 +64,19 @@ public class RegistrationProfile { this.applicationType = applicationType; } - public String toJSON() { + public boolean isSaasApp() { + return isSaasApp; + } + + public void setIsSaasApp(boolean isSaasApp) { + this.isSaasApp = isSaasApp; + } + + public String toJSON() { String jsonString = "{\"callbackUrl\": \"" + callbackUrl + "\",\"clientName\": \"" + clientName + "\", \"tokenScope\": " + "\"" + tokenScope + "\", \"owner\": \"" + owner + "\"," + "\"grantType\": \"" + grantType + - "\", \"saasApp\" :false }\n"; + "\", \"saasApp\" : " + isSaasApp + " }\n"; return jsonString; } } \ No newline at end of file diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/pom.xml b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/pom.xml index a4246e7d4..d46e3f2b6 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/pom.xml +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.devicemgt-plugins cdmf-transport-adapters - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../../pom.xml diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/pom.xml b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/pom.xml index b86ab8f08..1bfefbceb 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/pom.xml +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/pom.xml @@ -21,7 +21,7 @@ org.wso2.carbon.devicemgt-plugins cdmf-transport-adapters - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../../pom.xml @@ -95,6 +95,10 @@ javax.ws.rs jsr311-api + + io.github.openfeign + feign-slf4j + @@ -169,7 +173,9 @@ feign.auth, feign.codec, feign.gson, - javax.cache + javax.cache, + javax.net.ssl, + feign.slf4j * diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authorization/DeviceAuthorizer.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authorization/DeviceAuthorizer.java index 0edea4d1e..c4c40856e 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authorization/DeviceAuthorizer.java +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authorization/DeviceAuthorizer.java @@ -17,11 +17,16 @@ */ package org.wso2.carbon.device.mgt.output.adapter.websocket.authorization; +import feign.Client; import feign.Feign; import feign.FeignException; +import feign.Logger; +import feign.Request; +import feign.Response; import feign.gson.GsonDecoder; import feign.gson.GsonEncoder; import feign.jaxrs.JAXRSContract; +import feign.slf4j.Slf4jLogger; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.mgt.output.adapter.websocket.authentication.AuthenticationInfo; @@ -35,7 +40,16 @@ import org.wso2.carbon.device.mgt.output.adapter.websocket.util.PropertyUtils; import org.wso2.carbon.device.mgt.output.adapter.websocket.util.WebSocketSessionRequest; import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; import javax.websocket.Session; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -52,7 +66,7 @@ public class DeviceAuthorizer implements Authorizer { private static final String STAT_PERMISSION = "statsPermission"; private static final String DEVICE_ID = "deviceId"; private static final String DEVICE_TYPE = "deviceType"; - private static Log logger = LogFactory.getLog(DeviceAuthorizer.class); + private static Log log = LogFactory.getLog(DeviceAuthorizer.class); private static List statPermissions; public DeviceAuthorizer() { @@ -67,13 +81,13 @@ public class DeviceAuthorizer implements Authorizer { } } try { - deviceAccessAuthorizationAdminService = Feign.builder() - .requestInterceptor(new OAuthRequestInterceptor(globalProperties)) + deviceAccessAuthorizationAdminService = Feign.builder().client(getSSLClient()).logger(new Slf4jLogger()) + .logLevel(Logger.Level.FULL).requestInterceptor(new OAuthRequestInterceptor(globalProperties)) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .target(DeviceAccessAuthorizationAdminService.class, getDeviceMgtServerUrl(globalProperties) + CDMF_SERVER_BASE_CONTEXT); } catch (OutputEventAdapterException e) { - logger.error("Invalid value for deviceMgtServerUrl in globalProperties."); + log.error("Invalid value for deviceMgtServerUrl in globalProperties."); } } @@ -109,7 +123,7 @@ public class DeviceAuthorizer implements Authorizer { } } } catch (FeignException e) { - logger.error(e.getMessage(), e); + log.error(e.getMessage(), e); } } return false; @@ -118,7 +132,7 @@ public class DeviceAuthorizer implements Authorizer { private String getDeviceMgtServerUrl(Map properties) throws OutputEventAdapterException { String deviceMgtServerUrl = PropertyUtils.replaceProperty(properties.get(DEVICE_MGT_SERVER_URL)); if (deviceMgtServerUrl == null || deviceMgtServerUrl.isEmpty()) { - logger.error("deviceMgtServerUrl can't be empty "); + log.error("deviceMgtServerUrl can't be empty "); } return deviceMgtServerUrl; } @@ -130,4 +144,36 @@ public class DeviceAuthorizer implements Authorizer { } return null; } + + private static Client getSSLClient() { + return new Client.Default(getTrustedSSLSocketFactory(), new HostnameVerifier() { + @Override + public boolean verify(String s, SSLSession sslSession) { + return true; + } + }); + } + + private static SSLSocketFactory getTrustedSSLSocketFactory() { + try { + TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + public void checkClientTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + public void checkServerTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + } + }; + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, trustAllCerts, new java.security.SecureRandom()); + return sc.getSocketFactory(); + } catch (KeyManagementException | NoSuchAlgorithmException e) { + return null; + } + } } \ No newline at end of file diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authorization/client/OAuthRequestInterceptor.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authorization/client/OAuthRequestInterceptor.java index ffae0b797..e6f38d281 100755 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authorization/client/OAuthRequestInterceptor.java +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authorization/client/OAuthRequestInterceptor.java @@ -14,13 +14,18 @@ package org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client; +import feign.Client; import feign.Feign; +import feign.Logger; +import feign.Request; import feign.RequestInterceptor; import feign.RequestTemplate; +import feign.Response; import feign.auth.BasicAuthRequestInterceptor; import feign.gson.GsonDecoder; import feign.gson.GsonEncoder; import feign.jaxrs.JAXRSContract; +import feign.slf4j.Slf4jLogger; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto.AccessTokenInfo; @@ -31,6 +36,15 @@ import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client. import org.wso2.carbon.device.mgt.output.adapter.websocket.util.PropertyUtils; import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; import java.util.Map; /** @@ -49,7 +63,7 @@ public class OAuthRequestInterceptor implements RequestInterceptor { private ApiApplicationRegistrationService apiApplicationRegistrationService; private TokenIssuerService tokenIssuerService; - private static Log logger = LogFactory.getLog(OAuthRequestInterceptor.class); + private static Log log = LogFactory.getLog(OAuthRequestInterceptor.class); private static final String CONNECTION_USERNAME = "username"; private static final String CONNECTION_PASSWORD = "password"; @@ -73,17 +87,17 @@ public class OAuthRequestInterceptor implements RequestInterceptor { this.globalProperties = globalProperties; try { deviceMgtServerUrl = getDeviceMgtServerUrl(globalProperties); - refreshTimeOffset = getRefreshTimeOffset(globalProperties); + refreshTimeOffset = getRefreshTimeOffset(globalProperties) * 1000; username = getUsername(globalProperties); password = getPassword(globalProperties); tokenEndpoint = getTokenEndpoint(globalProperties); - apiApplicationRegistrationService = Feign.builder().requestInterceptor( - new BasicAuthRequestInterceptor(username, password)) + apiApplicationRegistrationService = Feign.builder().client(getSSLClient()).logger(new Slf4jLogger()) + .logLevel(Logger.Level.FULL).requestInterceptor(new BasicAuthRequestInterceptor(username, password)) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .target(ApiApplicationRegistrationService.class, deviceMgtServerUrl + API_APPLICATION_REGISTRATION_CONTEXT); } catch (OutputEventAdapterException e) { - logger.error("Invalid url: deviceMgtServerUrl" + deviceMgtServerUrl + " or tokenEndpoint:" + tokenEndpoint, + log.error("Invalid url: deviceMgtServerUrl" + deviceMgtServerUrl + " or tokenEndpoint:" + tokenEndpoint, e); } } @@ -100,12 +114,12 @@ public class OAuthRequestInterceptor implements RequestInterceptor { ApiApplicationKey apiApplicationKey = apiApplicationRegistrationService.register(apiRegistrationProfile); String consumerKey = apiApplicationKey.getConsumerKey(); String consumerSecret = apiApplicationKey.getConsumerSecret(); - tokenIssuerService = Feign.builder().requestInterceptor( - new BasicAuthRequestInterceptor(consumerKey, consumerSecret)) + tokenIssuerService = Feign.builder().client(getSSLClient()).logger(new Slf4jLogger()).logLevel(Logger.Level.FULL) + .requestInterceptor(new BasicAuthRequestInterceptor(consumerKey, consumerSecret)) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .target(TokenIssuerService.class, tokenEndpoint); tokenInfo = tokenIssuerService.getToken(PASSWORD_GRANT_TYPE, username, password, REQUIRED_SCOPE); - tokenInfo.setExpires_in(System.currentTimeMillis() + tokenInfo.getExpires_in()); + tokenInfo.setExpires_in(System.currentTimeMillis() + (tokenInfo.getExpires_in() * 1000)); } synchronized(this) { if (System.currentTimeMillis() + refreshTimeOffset > tokenInfo.getExpires_in()) { @@ -120,7 +134,7 @@ public class OAuthRequestInterceptor implements RequestInterceptor { private String getUsername(Map globalProperties) { String username = globalProperties.get(CONNECTION_USERNAME); if (username == null || username.isEmpty()) { - logger.error("username can't be empty "); + log.error("username can't be empty "); } return username; } @@ -128,7 +142,7 @@ public class OAuthRequestInterceptor implements RequestInterceptor { private String getPassword(Map globalProperties) { String password = globalProperties.get(CONNECTION_PASSWORD);; if (password == null || password.isEmpty()) { - logger.error("password can't be empty "); + log.error("password can't be empty "); } return password; } @@ -136,7 +150,7 @@ public class OAuthRequestInterceptor implements RequestInterceptor { private String getDeviceMgtServerUrl(Map globalProperties) throws OutputEventAdapterException { String deviceMgtServerUrl = globalProperties.get(DEVICE_MGT_SERVER_URL); if (deviceMgtServerUrl == null || deviceMgtServerUrl.isEmpty()) { - logger.error("deviceMgtServerUrl can't be empty "); + log.error("deviceMgtServerUrl can't be empty "); } return PropertyUtils.replaceProperty(deviceMgtServerUrl); } @@ -144,7 +158,7 @@ public class OAuthRequestInterceptor implements RequestInterceptor { private String getTokenEndpoint(Map globalProperties) throws OutputEventAdapterException { String tokenEndpoint = globalProperties.get(TOKEN_ENDPOINT_CONTEXT); if ( tokenEndpoint.isEmpty()) { - logger.error("tokenEndpoint can't be empty "); + log.error("tokenEndpoint can't be empty "); } return PropertyUtils.replaceProperty(tokenEndpoint); } @@ -154,9 +168,41 @@ public class OAuthRequestInterceptor implements RequestInterceptor { try { refreshTimeOffset = Long.parseLong(globalProperties.get(TOKEN_REFRESH_TIME_OFFSET)); } catch (NumberFormatException e) { - logger.error("refreshTimeOffset should be a number", e); + log.error("refreshTimeOffset should be a number", e); } return refreshTimeOffset; } + private static Client getSSLClient() { + return new Client.Default(getTrustedSSLSocketFactory(), new HostnameVerifier() { + @Override + public boolean verify(String s, SSLSession sslSession) { + return true; + } + }); + } + + private static SSLSocketFactory getTrustedSSLSocketFactory() { + try { + TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + public void checkClientTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + public void checkServerTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + } + }; + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, trustAllCerts, new java.security.SecureRandom()); + return sc.getSocketFactory(); + } catch (KeyManagementException | NoSuchAlgorithmException e) { + return null; + } + } + } diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/constants/WebsocketConstants.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/constants/WebsocketConstants.java index 6391fa07d..c5c3c01f2 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/constants/WebsocketConstants.java +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/constants/WebsocketConstants.java @@ -29,7 +29,7 @@ public class WebsocketConstants { public static final String SCOPE_IDENTIFIER = "scopes"; public static final String MAXIMUM_TOTAL_HTTP_CONNECTION = "maximumTotalHttpConnection"; public static final String MAXIMUM_HTTP_CONNECTION_PER_HOST = "maximumHttpConnectionPerHost"; - public static final String TOKEN_VALIDATION_ENDPOINT_URL = "keymanagerUrl"; + public static final String TOKEN_VALIDATION_ENDPOINT_URL = "tokenValidationUrl"; public static final String TOKEN_VALIDATION_CONTEX = "/services/OAuth2TokenValidationService"; public static final String USERNAME = "username"; public static final String PASSWORD = "password"; diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.xmpp/pom.xml b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.xmpp/pom.xml index 3029e8abd..a83083cb3 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.xmpp/pom.xml +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.xmpp/pom.xml @@ -20,7 +20,7 @@ org.wso2.carbon.devicemgt-plugins cdmf-transport-adapters - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../../pom.xml diff --git a/components/extensions/cdmf-transport-adapters/pom.xml b/components/extensions/cdmf-transport-adapters/pom.xml index bf715c897..8a9b56627 100644 --- a/components/extensions/cdmf-transport-adapters/pom.xml +++ b/components/extensions/cdmf-transport-adapters/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.devicemgt-plugins extensions - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/pom.xml b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/pom.xml index 7885a389a..947d4f022 100644 --- a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/pom.xml +++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.devicemgt-plugins mb-extensions - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml @@ -78,6 +78,10 @@ org.wso2.carbon javax.cache.wso2 + + io.github.openfeign + feign-slf4j + @@ -123,7 +127,9 @@ javax.xml.namespace, javax.xml.stream, org.wso2.carbon.base, - org.wso2.carbon.utils + org.wso2.carbon.utils, + javax.net.ssl, + feign.slf4j jsr311-api, diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/DeviceAccessBasedMQTTAuthorizer.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/DeviceAccessBasedMQTTAuthorizer.java index 0b9806962..6fd2c3464 100644 --- a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/DeviceAccessBasedMQTTAuthorizer.java +++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/DeviceAccessBasedMQTTAuthorizer.java @@ -18,11 +18,16 @@ package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization; +import feign.Client; import feign.Feign; import feign.FeignException; +import feign.Logger; +import feign.Request; +import feign.Response; import feign.gson.GsonDecoder; import feign.gson.GsonEncoder; import feign.jaxrs.JAXRSContract; +import feign.slf4j.Slf4jLogger; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.dna.mqtt.moquette.server.IAuthorizer; @@ -43,8 +48,16 @@ import org.wso2.carbon.user.api.UserStoreException; import javax.cache.Cache; import javax.cache.CacheConfiguration; -import javax.cache.CacheManager; import javax.cache.Caching; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; @@ -58,7 +71,7 @@ import java.util.concurrent.TimeUnit; public class DeviceAccessBasedMQTTAuthorizer implements IAuthorizer { private static final String UI_EXECUTE = "ui.execute"; - private static Log logger = LogFactory.getLog(DeviceAccessBasedMQTTAuthorizer.class); + private static Log log = LogFactory.getLog(DeviceAccessBasedMQTTAuthorizer.class); AuthorizationConfigurationManager MQTTAuthorizationConfiguration; private static final String CDMF_SERVER_BASE_CONTEXT = "/api/device-mgt/v1.0"; private static final String CACHE_MANAGER_NAME = "mqttAuthorizationCacheManager"; @@ -68,8 +81,8 @@ public class DeviceAccessBasedMQTTAuthorizer implements IAuthorizer { public DeviceAccessBasedMQTTAuthorizer() { this.MQTTAuthorizationConfiguration = AuthorizationConfigurationManager.getInstance(); - deviceAccessAuthorizationAdminService = Feign.builder() - .requestInterceptor(new OAuthRequestInterceptor()) + deviceAccessAuthorizationAdminService = Feign.builder().client(getSSLClient()).logger(new Slf4jLogger()) + .logLevel(Logger.Level.FULL).requestInterceptor(new OAuthRequestInterceptor()) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .target(DeviceAccessAuthorizationAdminService.class, MQTTAuthorizationConfiguration.getDeviceMgtServerUrl() + CDMF_SERVER_BASE_CONTEXT); @@ -108,7 +121,7 @@ public class DeviceAccessBasedMQTTAuthorizer implements IAuthorizer { } return false; } catch (FeignException e) { - logger.error(e.getMessage(), e); + log.error(e.getMessage(), e); return false; } } @@ -151,7 +164,7 @@ public class DeviceAccessBasedMQTTAuthorizer implements IAuthorizer { } } } catch (FeignException e) { - logger.error(e.getMessage(), e); + log.error(e.getMessage(), e); } } finally { PrivilegedCarbonContext.endTenantFlow(); @@ -195,7 +208,7 @@ public class DeviceAccessBasedMQTTAuthorizer implements IAuthorizer { userRealm.getAuthorizationManager().isUserAuthorized(username, permission, action); } catch (UserStoreException e) { String errorMsg = String.format("Unable to authorize the user : %s", username); - logger.error(errorMsg, e); + log.error(errorMsg, e); return false; } finally { PrivilegedCarbonContext.endTenantFlow(); @@ -224,4 +237,36 @@ public class DeviceAccessBasedMQTTAuthorizer implements IAuthorizer { } } + private static Client getSSLClient() { + return new Client.Default(getTrustedSSLSocketFactory(), new HostnameVerifier() { + @Override + public boolean verify(String s, SSLSession sslSession) { + return true; + } + }); + } + + private static SSLSocketFactory getTrustedSSLSocketFactory() { + try { + TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + public void checkClientTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + public void checkServerTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + } + }; + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, trustAllCerts, new java.security.SecureRandom()); + return sc.getSocketFactory(); + } catch (KeyManagementException | NoSuchAlgorithmException e) { + return null; + } + } + } \ No newline at end of file diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/client/OAuthRequestInterceptor.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/client/OAuthRequestInterceptor.java index f6cbd1c30..5f860985d 100755 --- a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/client/OAuthRequestInterceptor.java +++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/client/OAuthRequestInterceptor.java @@ -14,15 +14,22 @@ package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client; +import feign.Client; import feign.Feign; +import feign.Logger; +import feign.Request; import feign.RequestInterceptor; import feign.RequestTemplate; +import feign.Response; import feign.auth.BasicAuthRequestInterceptor; import feign.codec.EncodeException; import feign.codec.Encoder; import feign.gson.GsonDecoder; import feign.gson.GsonEncoder; import feign.jaxrs.JAXRSContract; +import feign.slf4j.Slf4jLogger; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto.AccessTokenInfo; import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto.ApiApplicationKey; import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto.ApiApplicationRegistrationService; @@ -30,6 +37,16 @@ import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto.TokenIssuerService; import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.config.AuthorizationConfigurationManager; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; + /** * This is a request interceptor to add oauth token header. */ @@ -45,16 +62,17 @@ public class OAuthRequestInterceptor implements RequestInterceptor { private static final String REQUIRED_SCOPE = "perm:authorization:verify"; private ApiApplicationRegistrationService apiApplicationRegistrationService; private TokenIssuerService tokenIssuerService; + private static Log log = LogFactory.getLog(OAuthRequestInterceptor.class); /** * Creates an interceptor that authenticates all requests. */ public OAuthRequestInterceptor() { - refreshTimeOffset = AuthorizationConfigurationManager.getInstance().getTokenRefreshTimeOffset(); + refreshTimeOffset = AuthorizationConfigurationManager.getInstance().getTokenRefreshTimeOffset() * 1000; String username = AuthorizationConfigurationManager.getInstance().getUsername(); String password = AuthorizationConfigurationManager.getInstance().getPassword(); - apiApplicationRegistrationService = Feign.builder().requestInterceptor( - new BasicAuthRequestInterceptor(username, password)) + apiApplicationRegistrationService = Feign.builder().client(getSSLClient()).logger(new Slf4jLogger()).logLevel( + Logger.Level.FULL).requestInterceptor(new BasicAuthRequestInterceptor(username, password)) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .target(ApiApplicationRegistrationService.class, AuthorizationConfigurationManager.getInstance().getDeviceMgtServerUrl() + @@ -75,13 +93,13 @@ public class OAuthRequestInterceptor implements RequestInterceptor { String consumerSecret = apiApplicationKey.getConsumerSecret(); String username = AuthorizationConfigurationManager.getInstance().getUsername(); String password = AuthorizationConfigurationManager.getInstance().getPassword(); - tokenIssuerService = Feign.builder().requestInterceptor( - new BasicAuthRequestInterceptor(consumerKey, consumerSecret)) + tokenIssuerService = Feign.builder().client(getSSLClient()).logger(new Slf4jLogger()).logLevel(Logger.Level.FULL) + .requestInterceptor(new BasicAuthRequestInterceptor(consumerKey, consumerSecret)) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .target(TokenIssuerService.class, AuthorizationConfigurationManager.getInstance().getTokenEndpoint()); tokenInfo = tokenIssuerService.getToken(PASSWORD_GRANT_TYPE, username, password, REQUIRED_SCOPE); - tokenInfo.setExpires_in(System.currentTimeMillis() + tokenInfo.getExpires_in()); + tokenInfo.setExpires_in(System.currentTimeMillis() + (tokenInfo.getExpires_in() * 1000)); } synchronized (this) { if (System.currentTimeMillis() + refreshTimeOffset > tokenInfo.getExpires_in()) { @@ -93,4 +111,36 @@ public class OAuthRequestInterceptor implements RequestInterceptor { template.header("Authorization", headerValue); } + private static Client getSSLClient() { + return new Client.Default(getTrustedSSLSocketFactory(), new HostnameVerifier() { + @Override + public boolean verify(String s, SSLSession sslSession) { + return true; + } + }); + } + + private static SSLSocketFactory getTrustedSSLSocketFactory() { + try { + TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + public void checkClientTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + public void checkServerTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + } + }; + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, trustAllCerts, new java.security.SecureRandom()); + return sc.getSocketFactory(); + } catch (KeyManagementException | NoSuchAlgorithmException e) { + return null; + } + } + } diff --git a/components/extensions/mb-extensions/pom.xml b/components/extensions/mb-extensions/pom.xml index e920fde00..72982c9dd 100644 --- a/components/extensions/mb-extensions/pom.xml +++ b/components/extensions/mb-extensions/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.devicemgt-plugins extensions - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/extensions/pom.xml b/components/extensions/pom.xml index 7c1457b78..b06e94acb 100644 --- a/components/extensions/pom.xml +++ b/components/extensions/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.devicemgt-plugins carbon-device-mgt-plugins-parent - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../../pom.xml diff --git a/components/extensions/siddhi-extensions/org.wso2.extension.siddhi.execution.json/pom.xml b/components/extensions/siddhi-extensions/org.wso2.extension.siddhi.execution.json/pom.xml index c90a2dabb..1defbead7 100644 --- a/components/extensions/siddhi-extensions/org.wso2.extension.siddhi.execution.json/pom.xml +++ b/components/extensions/siddhi-extensions/org.wso2.extension.siddhi.execution.json/pom.xml @@ -20,7 +20,7 @@ org.wso2.carbon.devicemgt-plugins siddhi-extensions - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/extensions/siddhi-extensions/pom.xml b/components/extensions/siddhi-extensions/pom.xml index 25332b34f..fc308eb39 100644 --- a/components/extensions/siddhi-extensions/pom.xml +++ b/components/extensions/siddhi-extensions/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.devicemgt-plugins extensions - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.analytics/pom.xml b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.analytics/pom.xml index 99cb9be3b..ef809db23 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.analytics/pom.xml +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.analytics/pom.xml @@ -21,7 +21,7 @@ org.wso2.carbon.devicemgt-plugins android-plugin - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/pom.xml b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/pom.xml index b21b40149..27acc9263 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/pom.xml +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/pom.xml @@ -21,7 +21,7 @@ android-plugin org.wso2.carbon.devicemgt-plugins - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/DeviceManagementAdminService.java b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/DeviceManagementAdminService.java index 78bb83361..f3c3c72b1 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/DeviceManagementAdminService.java +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/DeviceManagementAdminService.java @@ -58,7 +58,7 @@ import java.util.List; } ), tags = { - @Tag(name = "android", description = "") + @Tag(name = "android,device_management", description = "") } ) @Path("/admin/devices") diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/DeviceManagementService.java b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/DeviceManagementService.java index 5c7df5f1f..bb172a619 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/DeviceManagementService.java +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/DeviceManagementService.java @@ -56,7 +56,7 @@ import java.util.List; } ), tags = { - @Tag(name = "android", description = "") + @Tag(name = "android,device_management", description = "") } ) @Api(value = "Android Device Management", diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/DeviceTypeConfigurationService.java b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/DeviceTypeConfigurationService.java index 63f9fa4b4..5e2440941 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/DeviceTypeConfigurationService.java +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/DeviceTypeConfigurationService.java @@ -55,7 +55,7 @@ import javax.ws.rs.core.Response; } ), tags = { - @Tag(name = "android", description = "") + @Tag(name = "android,device_management", description = "") } ) @Api(value = "Android Configuration Management", description = "This API carries all the resource used to mange the Android platform configurations.") diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/EventReceiverService.java b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/EventReceiverService.java index 86a6df265..93b914a5f 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/EventReceiverService.java +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/EventReceiverService.java @@ -53,7 +53,7 @@ import javax.ws.rs.core.Response; } ), tags = { - @Tag(name = "android", description = "") + @Tag(name = "android,device_management", description = "") } ) @Api(value = "Event Receiver", description = "Event publishing/retrieving related APIs. To enable event publishing/retrieving you need to" + diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/impl/DeviceManagementServiceImpl.java b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/impl/DeviceManagementServiceImpl.java index e59fac68a..9efe83656 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/impl/DeviceManagementServiceImpl.java +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/impl/DeviceManagementServiceImpl.java @@ -20,15 +20,14 @@ package org.wso2.carbon.mdm.services.android.services.impl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.device.mgt.common.Device; -import org.wso2.carbon.device.mgt.common.DeviceIdentifier; -import org.wso2.carbon.device.mgt.common.DeviceManagementConstants; -import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.*; import org.wso2.carbon.device.mgt.common.app.mgt.Application; import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException; import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementException; import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; +import org.wso2.carbon.device.mgt.core.operation.mgt.CommandOperation; +import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil; import org.wso2.carbon.mdm.services.android.bean.ErrorResponse; import org.wso2.carbon.mdm.services.android.bean.wrapper.AndroidApplication; import org.wso2.carbon.mdm.services.android.bean.wrapper.AndroidDevice; @@ -219,7 +218,25 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { device.setProperties(androidDevice.getProperties()); boolean status = AndroidAPIUtils.getDeviceManagementService().enrollDevice(device); + if (status) { + List deviceIdentifiers = new ArrayList<>(); + deviceIdentifiers.add(new DeviceIdentifier(androidDevice.getDeviceIdentifier(), device.getType())); + + List taskOperaions = new ArrayList<>(); + taskOperaions.add(AndroidConstants.OperationCodes.APPLICATION_LIST); + taskOperaions.add(AndroidConstants.OperationCodes.DEVICE_INFO); + taskOperaions.add(AndroidConstants.OperationCodes.DEVICE_LOCATION); + for (String str : taskOperaions) { + CommandOperation operation = new CommandOperation(); + operation.setEnabled(true); + operation.setType(Operation.Type.COMMAND); + operation.setCode(str); + AndroidAPIUtils.getDeviceManagementService(). + addOperation(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID, + operation, deviceIdentifiers); + } + } PolicyManagerService policyManagerService = AndroidAPIUtils.getPolicyManagerService(); policyManagerService.getEffectivePolicy(new DeviceIdentifier(androidDevice.getDeviceIdentifier(), device.getType())); if (status) { @@ -249,6 +266,20 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { log.error(msg, e); throw new UnexpectedServerErrorException( new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()); + } catch (OperationManagementException e) { + String msg = "Error occurred while enforcing default enrollment policy upon android " + + "', which carries the id '" + + androidDevice.getDeviceIdentifier() + "'"; + log.error(msg, e); + throw new UnexpectedServerErrorException( + new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()); + } catch (InvalidDeviceException e) { + String msg = "Error occurred while enforcing default enrollment policy upon android " + + "', which carries the id '" + + androidDevice.getDeviceIdentifier() + "'"; + log.error(msg, e); + throw new UnexpectedServerErrorException( + new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()); } } diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/util/AndroidAPIUtils.java b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/util/AndroidAPIUtils.java index 65b7c60b9..e14b57dad 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/util/AndroidAPIUtils.java +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/util/AndroidAPIUtils.java @@ -106,7 +106,7 @@ public class AndroidAPIUtils { // PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); // GCMService gcmService = (GCMService) ctx.getOSGiService(GCMService.class, null); // if (gcmService == null) { -// String msg = "GCM service has not initialized."; +// String msg = "FCM service has not initialized."; // log.error(msg); // throw new IllegalStateException(msg); // } @@ -143,7 +143,7 @@ public class AndroidAPIUtils { DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID, operation, deviceIdentifiers); // if (activity != null) { // GCMService gcmService = getGCMService(); -// if (gcmService.isGCMEnabled()) { +// if (gcmService.isFCMEnabled()) { // List deviceIDList = deviceIDHolder.getValidDeviceIDList(); // List devices = new ArrayList(deviceIDList.size()); // for (DeviceIdentifier deviceIdentifier : deviceIDList) { @@ -471,6 +471,8 @@ public class AndroidAPIUtils { getProperty(prop.getValue(), "PASSCODE_ENABLED")); deviceInfo.getDeviceDetailsMap().put("operator", getProperty(prop.getValue(), "OPERATOR")); + deviceInfo.getDeviceDetailsMap().put("PhoneNumber", + getProperty(prop.getValue(), "PHONE_NUMBER")); } } } diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/webapp/WEB-INF/web.xml b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/webapp/WEB-INF/web.xml index b22bd2b5d..b62410431 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/webapp/WEB-INF/web.xml +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/webapp/WEB-INF/web.xml @@ -50,6 +50,10 @@ doAuthentication true + + isSharedWithAllTenants + true + diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/pom.xml b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/pom.xml index 027b1a800..b85ba7105 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/pom.xml +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/pom.xml @@ -23,13 +23,13 @@ android-plugin org.wso2.carbon.devicemgt-plugins - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml 4.0.0 org.wso2.carbon.device.mgt.mobile.android.ui - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT WSO2 Carbon - Mobile Android UI pom @@ -58,4 +58,4 @@ - \ No newline at end of file + diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/android-web-agent/app/conf/config.json b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/android-web-agent/app/conf/config.json index 9cd1e64b4..c52e88276 100755 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/android-web-agent/app/conf/config.json +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/android-web-agent/app/conf/config.json @@ -14,7 +14,8 @@ "apiManagerClientAppRegistrationServiceURL": "%https.ip%/api-application-registration/register/tenants", "grantType": "password refresh_token urn:ietf:params:oauth:grant-type:saml2-bearer", "tokenScope": "admin", - "callbackUrl": "%https.ip%/api/device-mgt/v1.0" + "callbackUrl": "%https.ip%/api/device-mgt/v1.0", + "samlGrantTypeName": "urn:ietf:params:oauth:grant-type:saml2-bearer" }, "tokenServiceURL": "%https.ip%/oauth2/token" }, diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/android-web-agent/app/modules/business-controllers/operation.js b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/android-web-agent/app/modules/business-controllers/operation.js index e96ffcdec..e97e0afb9 100755 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/android-web-agent/app/modules/business-controllers/operation.js +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/android-web-agent/app/modules/business-controllers/operation.js @@ -60,7 +60,7 @@ var operationModule = function () { feature["description"] = features[i].description; feature["deviceType"] = deviceType; feature["params"] = []; - var metaData = features[i].metadataEntries; + var metaData = features[i].metadataEntries; if (metaData) { for (var j = 0; j < metaData.length; j++) { feature["params"].push(metaData[j].value); diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/android-web-agent/app/modules/oauth/token-handler-utils.js b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/android-web-agent/app/modules/oauth/token-handler-utils.js index 2ed241d0d..614e79bb8 100755 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/android-web-agent/app/modules/oauth/token-handler-utils.js +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/android-web-agent/app/modules/oauth/token-handler-utils.js @@ -214,8 +214,8 @@ var utils = function () { // calling oauth provider token service endpoint var requestURL = deviceMgtProps["oauthProvider"]["tokenServiceURL"]; - var requestPayload = "grant_type=urn:ietf:params:oauth:grant-type:saml2-bearer&" + - "assertion=" + encodeURIComponent(encodedAssertion) + "&scope=" + scopes; + var requestPayload = "grant_type=" + + deviceMgtProps["oauthProvider"]["appRegistration"]["samlGrantTypeName"] + + "&" + "assertion=" + encodeURIComponent(encodedAssertion) + "&scope=" + scopes; var xhr = new XMLHttpRequest(); xhr.open("POST", requestURL, false); diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/android-web-agent/app/pages/mdm.page.enrollments.android.download-agent/public/asset/android-agent.apk b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/android-web-agent/app/pages/mdm.page.enrollments.android.download-agent/public/asset/android-agent.apk index 6f5ead8bc..de63c0634 100644 Binary files a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/android-web-agent/app/pages/mdm.page.enrollments.android.download-agent/public/asset/android-agent.apk and b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/android-web-agent/app/pages/mdm.page.enrollments.android.download-agent/public/asset/android-agent.apk differ diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/device-view.hbs b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/device-view.hbs index 4b2dfe84a..0577d7482 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/device-view.hbs +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/device-view.hbs @@ -364,16 +364,18 @@
    + data-locations="{{device.locationHistory}}">

    - + {{#unless isCloud}} + - Add Geo Fencing - + Add Geo Fencing + + {{/unless}} {{else}}

    diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/device-view.js b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/device-view.js index 0a0bba6ba..ea56974af 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/device-view.js +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/device-view.js @@ -216,6 +216,7 @@ function onRequest(context) { deviceViewData["permissions"] = permissions; deviceViewData["portalUrl"] = devicemgtProps['portalURL']; + deviceViewData["isCloud"] = devicemgtProps['isCloud']; deviceViewData["anchor"] = encodeURI(JSON.stringify({ "device" : { "id" : deviceId, "type" : deviceType}})); return deviceViewData; } diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/public/js/device-detail.js b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/public/js/device-detail.js index c628f1260..0d41ff274 100755 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/public/js/device-detail.js +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/public/js/device-detail.js @@ -26,32 +26,16 @@ var InitiateViewOption = null; var payload = [deviceIdentifier]; var operationTable; var serviceUrl; + var serviceUrlLocal = "/api/device-mgt/android/v1.0/admin/devices/location"; if (deviceType == "ios") { serviceUrl = "/ios/operation/deviceinfo"; } else if (deviceType == "android") { //var serviceUrl = "/mdm-android-agent/operation/device-info"; serviceUrl = "/api/device-mgt/android/v1.0/admin/devices/info"; + serviceUrlLocal = "/api/device-mgt/android/v1.0/admin/devices/location"; } - if (serviceUrl) { - invokerUtil.post( - serviceUrl, - payload, - // success-callback - function () { - $(".panel-body").show(); - }, - // error-callback - function () { - var defaultInnerHTML = - "

    Device data may not have been updated. Please refresh to try again.

    "; - $(".panel-body").append(defaultInnerHTML); - } - ); - } - - $(".media.tab-responsive [data-toggle=tab]").on("shown.bs.tab", function (e) { var activeTabPane = $(e.target).attr("href"); var activeListGroupItem = $(".media .list-group-item.active"); diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/public/js/load-map.js b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/public/js/load-map.js index 10c4ec453..af0d1e5d8 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/public/js/load-map.js +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/public/js/load-map.js @@ -19,7 +19,7 @@ var map; function loadLeafletMap() { - + var deviceLocationID = "#device-location", locations = $(deviceLocationID).data("locations"), location_lat = $(deviceLocationID).data("lat"), @@ -28,7 +28,7 @@ function loadLeafletMap() { zoomLevel = 13, tileSet = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", attribution = "© OpenStreetMap contributors"; - if (locations) { + if (locations && locations.locations.length > 0) { var locationSets = locations.locations; map = L.map(container).setView([locationSets[0].lat, locationSets[0].lng], zoomLevel); @@ -46,9 +46,10 @@ function loadLeafletMap() { this.closePopup(); }); } - $("#map-error").hide(); $("#device-location").show(); + setTimeout(function(){ map.invalidateSize()}, 400); + } else if (location_long && location_lat) { map = L.map(container).setView([location_lat, location_long], zoomLevel); @@ -61,7 +62,9 @@ function loadLeafletMap() { m.on('mouseout', function (e) { this.closePopup(); }); - + $("#map-error").hide(); + $("#device-location").show(); + setTimeout(function(){ map.invalidateSize()}, 400); } else { $("#device-location").hide(); $("#map-error").show(); diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.operation-bar/operation-bar.hbs b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.operation-bar/operation-bar.hbs index 688302a90..3a5a60956 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.operation-bar/operation-bar.hbs +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.operation-bar/operation-bar.hbs @@ -113,11 +113,6 @@

    {{/each}} -{{else}} -
    -

    - Operations Loading Failed!

    -
    {{/if}} -
    +
    -

    diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.platform.configuration/public/js/platform-configuration.js b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.platform.configuration/public/js/platform-configuration.js index ec2af9639..5d75b35d9 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.platform.configuration/public/js/platform-configuration.js +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.platform.configuration/public/js/platform-configuration.js @@ -29,7 +29,7 @@ function isPositiveInteger(str) { var notifierTypeConstants = { "LOCAL": "1", - "GCM": "2" + "FCM": "2" }; // Constants to define platform types available var platformTypeConstants = { @@ -47,8 +47,8 @@ var responseCodes = { var configParams = { "NOTIFIER_TYPE": "notifierType", "NOTIFIER_FREQUENCY": "notifierFrequency", - "GCM_API_KEY": "gcmAPIKey", - "GCM_SENDER_ID": "gcmSenderId", + "FCM_API_KEY": "fcmAPIKey", + "FCM_SENDER_ID": "fcmSenderId", "ANDROID_EULA": "androidEula", "IOS_EULA": "iosEula", "CONFIG_COUNTRY": "configCountry", @@ -81,7 +81,7 @@ var configParams = { }; $(document).ready(function () { - $("#gcm-inputs").hide(); + $("#fcm-inputs").hide(); tinymce.init({ selector: "textarea", height:500, @@ -113,17 +113,17 @@ $(document).ready(function () { var config = data.configuration[i]; if (config.name == configParams["NOTIFIER_TYPE"]) { $("#android-config-notifier").val(config.value); - if (config.value != notifierTypeConstants["GCM"]) { - $("#gcm-inputs").hide(); + if (config.value != notifierTypeConstants["FCM"]) { + $("#fcm-inputs").hide(); $("#local-inputs").show(); } else { - $("#gcm-inputs").show(); + $("#fcm-inputs").show(); $("#local-inputs").hide(); } } else if (config.name == configParams["NOTIFIER_FREQUENCY"]) { $("input#android-config-notifier-frequency").val(config.value / 1000); - } else if (config.name == configParams["GCM_API_KEY"]) { - $("input#android-config-gcm-api-key").val(config.value); + } else if (config.name == configParams["FCM_API_KEY"]) { + $("input#android-config-fcm-api-key").val(config.value); } else if (config.name == configParams["ANDROID_EULA"]) { $("#android-eula").val(config.value); } @@ -139,12 +139,12 @@ $(document).ready(function () { $("#android-config-notifier").change(function () { var notifierType = $("#android-config-notifier").find("option:selected").attr("value"); - if (notifierType != notifierTypeConstants["GCM"]) { - $("#gcm-inputs").hide(); + if (notifierType != notifierTypeConstants["FCM"]) { + $("#fcm-inputs").hide(); $("#local-inputs").show(); } else { $("#local-inputs").hide(); - $("#gcm-inputs").show(); + $("#fcm-inputs").show(); } }); @@ -156,8 +156,8 @@ $(document).ready(function () { $("button#save-android-btn").click(function () { var notifierType = $("#android-config-notifier").find("option:selected").attr("value"); var notifierFrequency = $("input#android-config-notifier-frequency").val(); - var gcmAPIKey = $("input#android-config-gcm-api-key").val(); - var gcmSenderId = "sender_id"; + var fcmAPIKey = $("input#android-config-fcm-api-key").val(); + var fcmSenderId = "sender_id"; var androidLicense = tinyMCE.activeEditor.getContent(); var errorMsgWrapper = "#android-config-error-msg"; var errorMsg = "#android-config-error-msg span"; @@ -167,7 +167,7 @@ $(document).ready(function () { } else if (notifierType == notifierTypeConstants["LOCAL"] && !isPositiveInteger(notifierFrequency)) { $(errorMsg).text("Provided notifier frequency is invalid. "); $(errorMsgWrapper).removeClass("hidden"); - } else if (notifierType == notifierTypeConstants["GCM"] && !gcmAPIKey) { + } else if (notifierType == notifierTypeConstants["FCM"] && !fcmAPIKey) { $(errorMsg).text("FCM API Key is a required field. It cannot be empty."); $(errorMsgWrapper).removeClass("hidden"); } else { @@ -187,15 +187,15 @@ $(document).ready(function () { "contentType": "text" }; - var gcmKey = { - "name": configParams["GCM_API_KEY"], - "value": gcmAPIKey, + var fcmKey = { + "name": configParams["FCM_API_KEY"], + "value": fcmAPIKey, "contentType": "text" }; - var gcmId = { - "name": configParams["GCM_SENDER_ID"], - "value": gcmSenderId, + var fcmId = { + "name": configParams["FCM_SENDER_ID"], + "value": fcmSenderId, "contentType": "text" }; @@ -208,9 +208,9 @@ $(document).ready(function () { configList.push(type); configList.push(frequency); configList.push(androidEula); - if (notifierType == notifierTypeConstants["GCM"]) { - configList.push(gcmKey); - configList.push(gcmId); + if (notifierType == notifierTypeConstants["FCM"]) { + configList.push(fcmKey); + configList.push(fcmId); } addConfigFormData.type = platformTypeConstants["ANDROID"]; diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/css/styles.css b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/css/styles.css index 1a65500ff..56dc06903 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/css/styles.css +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/css/styles.css @@ -57,4 +57,7 @@ hr { .doc-link a { color: #006eff; +} +.enrollment-qr-container canvas { + width: 24%; } \ No newline at end of file diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/images/install_agent.png b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/images/install_agent.png new file mode 100644 index 000000000..8e5230965 Binary files /dev/null and b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/images/install_agent.png differ diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/images/login.png b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/images/login.png new file mode 100644 index 000000000..9a01b0ac4 Binary files /dev/null and b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/images/login.png differ diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/images/registration.png b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/images/registration.png new file mode 100644 index 000000000..7187b6d20 Binary files /dev/null and b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/images/registration.png differ diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/images/set_profile.png b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/images/set_profile.png new file mode 100644 index 000000000..23e6002df Binary files /dev/null and b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/images/set_profile.png differ diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/js/type-view.js b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/js/type-view.js index 7d9c77921..ea6f396cb 100755 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/js/type-view.js +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/js/type-view.js @@ -20,7 +20,7 @@ var modalPopup = ".modal", modalPopupContainer = modalPopup + " .modal-content", modalPopupContent = modalPopup + " .modal-content"; -var emmAdminBasePath = "/api/device-mgt/v1.0"; +var backendEndBasePath = "/api/device-mgt/v1.0"; //function openCollapsedNav() { // $(".wr-hidden-nav-toggle-btn").addClass("active"); @@ -102,7 +102,7 @@ function loadNewNotificationsOnSideViewPanel() { if ($("#right-sidebar").attr("is-authorized") == "false") { $("#notification-bubble-wrapper").remove(); } else { - var serviceURL = emmAdminBasePath + "/notifications?status=NEW"; + var serviceURL = backendEndBasePath + "/notifications?status=NEW"; invokerUtil.get(serviceURL, updateNotificationCountOnSuccess, updateNotificationCountOnError); loadNewNotifications(); } @@ -117,7 +117,7 @@ function loadNewNotifications() { var currentUser = notifications.data("currentUser"); $.template("notification-listing", notifications.attr("src"), function (template) { - var serviceURL = emmAdminBasePath + "/notifications?offset=0&limit=5&status=NEW"; + var serviceURL = backendEndBasePath + "/notifications?offset=0&limit=5&status=NEW"; invokerUtil.get( serviceURL, // on success @@ -349,6 +349,9 @@ $.fn.collapse_nav_sub = function () { $(document).ready(function () { $.sidebar_toggle(); + + generateQRCode(".enrollment-qr-container"); + if (typeof $.fn.collapse == 'function') { $('.navbar-collapse.tiles').on('shown.bs.collapse', function () { $(this).collapse_nav_sub(); @@ -359,7 +362,7 @@ $(document).ready(function () { $("#right-sidebar").on("click", ".new-notification", function () { var notificationId = $(this).data("id"); var redirectUrl = $(this).data("url"); - var markAsReadNotificationsEpr = emmAdminBasePath + "/notifications/" + notificationId + "/mark-checked"; + var markAsReadNotificationsEpr = backendEndBasePath + "/notifications/" + notificationId + "/mark-checked"; var messageSideBar = ".sidebar-messages"; invokerUtil.put( @@ -382,3 +385,30 @@ $(document).ready(function () { ); }); }); + +function artifactUpload() { + var contentType = "application/json"; + + var urix = backendEndBasePath + "/admin/devicetype/deploy/android"; + var defaultStatusClasses = "fw fw-stack-1x"; + var content = $("#android-statistic-response-template").find(".content"); + var title = content.find("#title"); + var statusIcon = content.find("#status-icon"); + var data = {} + invokerUtil.post(urix, data, function (data) { + title.html("Deploying statistic artifacts. Please wait..."); + statusIcon.attr("class", defaultStatusClasses + " fw-check"); + $(modalPopupContent).html(content.html()); + showPopup(); + setTimeout(function () { + hidePopup(); + location.reload(true); + }, 5000); + + }, function (jqXHR) { + title.html("Failed to deploy artifacts, Please contact administrator."); + statusIcon.attr("class", defaultStatusClasses + " fw-error"); + $(modalPopupContent).html(content.html()); + showPopup(); + }, contentType); +} \ No newline at end of file diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/type-view.hbs b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/type-view.hbs index a5a93a803..2e60d40dd 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/type-view.hbs +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/type-view.hbs @@ -2,43 +2,140 @@ {{unit "cdmf.unit.device.type.qr-modal" enrollmentURL=enrollmentURL deviceTypeName="Android"}} {{unit "cdmf.unit.device.type.email.invite-modal" deviceTypeView="android"}} -
    -

    Android Mobile

    -
    +
    +
    +

    DOWNLOAD THE ANDROID AGENT

    +
    +
    -
    - + +
    + +
    +

    Scan to download the Android Agent.

    +
    +

    or

    + + + + {{#if isCloud}} + + {{else}} + + {{/if}} + +
    -
    +
    +
    +

    START ENROLLING YOUR DEVICE

    +
    +
    +
    -

    What it Does

    -
    -

    Connect and manage your Android device with WSO2 IoT Server.

    -
    +{{#if isCloud}} +
    - Enroll Device - Download APK - Invite by Email +
    +
    Step 1
    +

    Let's start by installing the Android agent on your device. Open the downloaded file, and tap + INSTALL.

    + +
    +
    +
    Step 2
    +

    Enter your: +

    +

      +
    • Username: username/email that you used to sign in.
    • +
    • Password: the WSO2 Cloud password.
    • +
    • Organization: the name of the organization.
    • +
    + +
    +{{else}} +
    +
    +
    Step 1
    +

    Let's start by installing the Android agent on your device. Open the downloaded file, and tap + INSTALL.

    + +
    - +
    +
    Step 2
    +

    Tap Skip to proceed with the default enrollment process.

    + +
    +
    +
    Step 3
    +

    Enter the server address based on your environment, in the text box provided.

    + +
    +
    +
    Step 4
    +

    Enter your: +

    +

      +
    • Username: username/email that you used to sign in to IoT server.
    • +
    • Password: the WSO2 Iot server password.
    • +
    • Domain: the name of the domain.
    • +
    + +
    +{{/if}} -

    What You Need

    -
    -
      -
    • STEP 01 Android - Mobile. -
    • -
    • STEP 02 Go ahead - and click [Enroll Device]. -
    • -
    • STEP 03 Proceed - to the [Prepare] section. -
    • -
    -
    +
    + -
    + -
    +
    {{#zone "topCss"}} {{css "css/styles.css"}} diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/type-view.js b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/type-view.js index a5c2a32bb..ec164b657 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/type-view.js +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/type-view.js @@ -19,6 +19,22 @@ function onRequest(context){ var viewModel = {}; var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"]; + //uncomment this to enable analytics artifact deployment + //var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"]; + //var url = devicemgtProps["httpsURL"] + "/api/device-mgt/v1.0/admin/devicetype/deploy/android/status"; + //serviceInvokers.XMLHttp.get( + // url, function (responsePayload) { + // var responseContent = responsePayload.status; + // new Log().error(responseContent); + // if ("204" == responsePayload.status) { + // viewModel["displayStatus"] = "Display"; + // } + // }, + // function (responsePayload) { + // //do nothing. + // } + //); + viewModel["isCloud"] = devicemgtProps["isCloud"]; viewModel["hostName"] = devicemgtProps["httpsURL"]; viewModel["enrollmentURL"] = devicemgtProps["generalConfig"]["host"] + devicemgtProps["androidEnrollmentDir"]; return viewModel; diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/pom.xml b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/pom.xml index bd97bd6eb..57957f785 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/pom.xml +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/pom.xml @@ -22,7 +22,7 @@ android-plugin org.wso2.carbon.devicemgt-plugins - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/AndroidDeviceManagementService.java b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/AndroidDeviceManagementService.java index 211619e28..f5b762db0 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/AndroidDeviceManagementService.java +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/AndroidDeviceManagementService.java @@ -20,10 +20,7 @@ package org.wso2.carbon.device.mgt.mobile.android.impl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.device.mgt.common.DeviceManagementException; -import org.wso2.carbon.device.mgt.common.DeviceManager; -import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig; -import org.wso2.carbon.device.mgt.common.ProvisioningConfig; +import org.wso2.carbon.device.mgt.common.*; import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager; import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry; import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; @@ -46,8 +43,8 @@ public class AndroidDeviceManagementService implements DeviceManagementService { public static final String DEVICE_TYPE_ANDROID = "android"; private static final String SUPER_TENANT_DOMAIN = "carbon.super"; private static final String NOTIFIER_PROPERTY = "notifierType"; - private static final String GCM_API_KEY = "gcmAPIKey"; - private static final String GCM_SENDER_ID = "gcmSenderId"; + private static final String FCM_API_KEY = "fcmAPIKey"; + private static final String FCM_SENDER_ID = "fcmSenderId"; private PolicyMonitoringManager policyMonitoringManager; @Override @@ -95,9 +92,9 @@ public class AndroidDeviceManagementService implements DeviceManagementService { int notifierType = Integer.parseInt(notifierValue); if (notifierType == 2) { HashMap config = new HashMap<>(); - config.put(GCM_API_KEY, this.getConfigProperty(configuration, GCM_API_KEY)); - config.put(GCM_SENDER_ID, this.getConfigProperty(configuration, GCM_SENDER_ID)); - return new PushNotificationConfig(AndroidPluginConstants.NotifierType.GCM, config); + config.put(FCM_API_KEY, this.getConfigProperty(configuration, FCM_API_KEY)); + config.put(FCM_SENDER_ID, this.getConfigProperty(configuration, FCM_SENDER_ID)); + return new PushNotificationConfig(AndroidPluginConstants.NotifierType.FCM, config); } } } @@ -113,6 +110,11 @@ public class AndroidDeviceManagementService implements DeviceManagementService { return policyMonitoringManager; } + @Override + public InitialOperationConfig getInitialOperationConfig() { + return null; + } + private String getConfigProperty(List configs, String propertyName) { for (ConfigurationEntry entry : configs) { if (propertyName.equals(entry.getName())) { diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/dao/impl/AndroidDeviceDAOImpl.java b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/dao/impl/AndroidDeviceDAOImpl.java index 8df98747f..416a4d90d 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/dao/impl/AndroidDeviceDAOImpl.java +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/dao/impl/AndroidDeviceDAOImpl.java @@ -52,7 +52,7 @@ public class AndroidDeviceDAOImpl implements MobileDeviceDAO{ try { conn = AndroidDAOFactory.getConnection(); String selectDBQuery = - "SELECT DEVICE_ID, GCM_TOKEN, DEVICE_INFO, DEVICE_MODEL, SERIAL, " + + "SELECT DEVICE_ID, FCM_TOKEN, DEVICE_INFO, DEVICE_MODEL, SERIAL, " + "VENDOR, MAC_ADDRESS, DEVICE_NAME, LATITUDE, LONGITUDE, IMEI, IMSI, OS_VERSION, OS_BUILD_DATE" + " FROM AD_DEVICE WHERE DEVICE_ID = ?"; stmt = conn.prepareStatement(selectDBQuery); @@ -73,7 +73,7 @@ public class AndroidDeviceDAOImpl implements MobileDeviceDAO{ mobileDevice.setOsBuildDate(rs.getString(AndroidPluginConstants.OS_BUILD_DATE)); Map propertyMap = new HashMap(); - propertyMap.put(AndroidPluginConstants.GCM_TOKEN, rs.getString(AndroidPluginConstants.GCM_TOKEN)); + propertyMap.put(AndroidPluginConstants.FCM_TOKEN, rs.getString(AndroidPluginConstants.FCM_TOKEN)); propertyMap.put(AndroidPluginConstants.DEVICE_INFO, rs.getString(AndroidPluginConstants.DEVICE_INFO)); propertyMap.put(AndroidPluginConstants.DEVICE_NAME, rs.getString(AndroidPluginConstants.DEVICE_NAME)); mobileDevice.setDeviceProperties(propertyMap); @@ -103,7 +103,7 @@ public class AndroidDeviceDAOImpl implements MobileDeviceDAO{ try { conn = AndroidDAOFactory.getConnection(); String createDBQuery = - "INSERT INTO AD_DEVICE(DEVICE_ID, GCM_TOKEN, DEVICE_INFO, SERIAL, " + + "INSERT INTO AD_DEVICE(DEVICE_ID, FCM_TOKEN, DEVICE_INFO, SERIAL, " + "VENDOR, MAC_ADDRESS, DEVICE_NAME, LATITUDE, LONGITUDE, IMEI, IMSI, " + "OS_VERSION, DEVICE_MODEL, OS_BUILD_DATE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; @@ -111,7 +111,7 @@ public class AndroidDeviceDAOImpl implements MobileDeviceDAO{ stmt.setString(1, mobileDevice.getMobileDeviceId()); Map properties = mobileDevice.getDeviceProperties(); - stmt.setString(2, properties.get(AndroidPluginConstants.GCM_TOKEN)); + stmt.setString(2, properties.get(AndroidPluginConstants.FCM_TOKEN)); stmt.setString(3, properties.get(AndroidPluginConstants.DEVICE_INFO)); stmt.setString(4, mobileDevice.getSerial()); stmt.setString(5, mobileDevice.getVendor()); @@ -149,13 +149,13 @@ public class AndroidDeviceDAOImpl implements MobileDeviceDAO{ try { conn = AndroidDAOFactory.getConnection(); String updateDBQuery = - "UPDATE AD_DEVICE SET GCM_TOKEN = ?, DEVICE_INFO = ?, SERIAL = ?, VENDOR = ?, " + + "UPDATE AD_DEVICE SET FCM_TOKEN = ?, DEVICE_INFO = ?, SERIAL = ?, VENDOR = ?, " + "MAC_ADDRESS = ?, DEVICE_NAME = ?, LATITUDE = ?, LONGITUDE = ?, IMEI = ?, " + "IMSI = ?, OS_VERSION = ?, DEVICE_MODEL = ?, OS_BUILD_DATE = ? WHERE DEVICE_ID = ?"; stmt = conn.prepareStatement(updateDBQuery); Map properties = mobileDevice.getDeviceProperties(); - stmt.setString(1, properties.get(AndroidPluginConstants.GCM_TOKEN)); + stmt.setString(1, properties.get(AndroidPluginConstants.FCM_TOKEN)); stmt.setString(2, properties.get(AndroidPluginConstants.DEVICE_INFO)); stmt.setString(3, mobileDevice.getSerial()); stmt.setString(4, mobileDevice.getVendor()); @@ -227,7 +227,7 @@ public class AndroidDeviceDAOImpl implements MobileDeviceDAO{ try { conn = AndroidDAOFactory.getConnection(); String selectDBQuery = - "SELECT DEVICE_ID, GCM_TOKEN, DEVICE_INFO, DEVICE_MODEL, SERIAL, " + + "SELECT DEVICE_ID, FCM_TOKEN, DEVICE_INFO, DEVICE_MODEL, SERIAL, " + "VENDOR, MAC_ADDRESS, DEVICE_NAME, LATITUDE, LONGITUDE, IMEI, IMSI, OS_VERSION, OS_BUILD_DATE " + "FROM AD_DEVICE"; stmt = conn.prepareStatement(selectDBQuery); @@ -247,7 +247,7 @@ public class AndroidDeviceDAOImpl implements MobileDeviceDAO{ mobileDevice.setOsBuildDate(rs.getString(AndroidPluginConstants.OS_BUILD_DATE)); Map propertyMap = new HashMap<>(); - propertyMap.put(AndroidPluginConstants.GCM_TOKEN, rs.getString(AndroidPluginConstants.GCM_TOKEN)); + propertyMap.put(AndroidPluginConstants.FCM_TOKEN, rs.getString(AndroidPluginConstants.FCM_TOKEN)); propertyMap.put(AndroidPluginConstants.DEVICE_INFO, rs.getString(AndroidPluginConstants.DEVICE_INFO)); propertyMap.put(AndroidPluginConstants.DEVICE_NAME, rs.getString(AndroidPluginConstants.DEVICE_NAME)); mobileDevice.setDeviceProperties(propertyMap); diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/gcm/GCMResult.java b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/fcm/FCMResult.java similarity index 89% rename from components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/gcm/GCMResult.java rename to components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/fcm/FCMResult.java index f9c770358..530a56e30 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/gcm/GCMResult.java +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/fcm/FCMResult.java @@ -16,12 +16,12 @@ * under the License. */ -package org.wso2.carbon.device.mgt.mobile.android.impl.gcm; +package org.wso2.carbon.device.mgt.mobile.android.impl.fcm; /** - * Represents model object for holding GCM response data. + * Represents model object for holding FCM response data. */ -public class GCMResult { +public class FCMResult { private String errorMsg; private String msg; diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/gcm/GCMService.java b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/fcm/FCMService.java similarity index 67% rename from components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/gcm/GCMService.java rename to components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/fcm/FCMService.java index bfa1685fa..15978f7a9 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/gcm/GCMService.java +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/fcm/FCMService.java @@ -16,7 +16,7 @@ * under the License. */ -package org.wso2.carbon.device.mgt.mobile.android.impl.gcm; +package org.wso2.carbon.device.mgt.mobile.android.impl.fcm; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -26,17 +26,17 @@ import java.util.ArrayList; import java.util.List; /** - * GCM notification service implementation for Android platform. + * FCM notification service implementation for Android platform. */ -public class GCMService { +public class FCMService { - private static final Log log = LogFactory.getLog(GCMService.class); + private static final Log log = LogFactory.getLog(FCMService.class); private static final String NOTIFIER_TYPE = "notifierType"; - private static final String GCM_NOTIFIER_CODE = "2"; + private static final String FCM_NOTIFIER_CODE = "2"; - public boolean isGCMEnabled() { - String notifierType = GCMUtil.getConfigurationProperty(NOTIFIER_TYPE); - if (GCM_NOTIFIER_CODE.equals(notifierType)) { + public boolean isFCMEnabled() { + String notifierType = FCMUtil.getConfigurationProperty(NOTIFIER_TYPE); + if (FCM_NOTIFIER_CODE.equals(notifierType)) { return true; } return false; @@ -45,20 +45,20 @@ public class GCMService { public void sendNotification(String messageData, Device device) { List devices = new ArrayList<>(1); devices.add(device); - GCMResult result = GCMUtil.sendWakeUpCall(messageData, devices); + FCMResult result = FCMUtil.sendWakeUpCall(messageData, devices); if (result.getStatusCode() != 200) { - log.error("Exception occurred while sending the GCM notification : " + result.getErrorMsg()); + log.error("Exception occurred while sending the FCM notification : " + result.getErrorMsg()); } } public void sendNotification(String messageData, List devices) { - GCMResult result = GCMUtil.sendWakeUpCall(messageData, devices); + FCMResult result = FCMUtil.sendWakeUpCall(messageData, devices); if (result.getStatusCode() != 200) { - log.error("Exception occurred while sending the GCM notification : " + result.getErrorMsg()); + log.error("Exception occurred while sending the FCM notification : " + result.getErrorMsg()); } } public void resetTenantConfigCache() { - GCMUtil.resetTenantConfigCache(); + FCMUtil.resetTenantConfigCache(); } } \ No newline at end of file diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/gcm/GCMUtil.java b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/fcm/FCMUtil.java similarity index 81% rename from components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/gcm/GCMUtil.java rename to components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/fcm/FCMUtil.java index 381468bdf..c56102268 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/gcm/GCMUtil.java +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/fcm/FCMUtil.java @@ -16,7 +16,7 @@ * under the License. */ -package org.wso2.carbon.device.mgt.mobile.android.impl.gcm; +package org.wso2.carbon.device.mgt.mobile.android.impl.fcm; import com.google.gson.JsonArray; import com.google.gson.JsonObject; @@ -45,32 +45,32 @@ import java.util.HashMap; import java.util.List; /** - * Implements utility methods used by GCMService. + * Implements utility methods used by FCMService. */ -public class GCMUtil { +public class FCMUtil { - private static final Log log = LogFactory.getLog(GCMService.class); + private static final Log log = LogFactory.getLog(FCMService.class); - private final static String GCM_ENDPOINT = "https://fcm.googleapis.com/fcm/send"; - private static final String GCM_API_KEY = "gcmAPIKey"; + private final static String FCM_ENDPOINT = "https://fcm.googleapis.com/fcm/send"; + private static final String FCM_API_KEY = "fcmAPIKey"; private static final int TIME_TO_LIVE = 60; private static final int HTTP_STATUS_CODE_OK = 200; private static HashMap tenantConfigurationCache = new HashMap<>(); - public static GCMResult sendWakeUpCall(String message, List devices) { - GCMResult result = new GCMResult(); + public static FCMResult sendWakeUpCall(String message, List devices) { + FCMResult result = new FCMResult(); - byte[] bytes = getGCMRequest(message, getGCMTokens(devices)).getBytes(); + byte[] bytes = getFCMRequest(message, getFCMTokens(devices)).getBytes(); HttpURLConnection conn; try { - conn = (HttpURLConnection) (new URL(GCM_ENDPOINT)).openConnection(); + conn = (HttpURLConnection) (new URL(FCM_ENDPOINT)).openConnection(); conn.setDoOutput(true); conn.setUseCaches(false); conn.setFixedLengthStreamingMode(bytes.length); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/json"); - conn.setRequestProperty("Authorization", "key=" + getConfigurationProperty(GCM_API_KEY)); + conn.setRequestProperty("Authorization", "key=" + getConfigurationProperty(FCM_API_KEY)); OutputStream out = conn.getOutputStream(); out.write(bytes); @@ -86,7 +86,7 @@ public class GCMUtil { } catch (ProtocolException e) { log.error("Exception occurred while setting the HTTP protocol.", e); } catch (IOException ex) { - log.error("Exception occurred while sending the GCM request.", ex); + log.error("Exception occurred while sending the FCM request.", ex); } return result; @@ -114,16 +114,16 @@ public class GCMUtil { return null; } - private static String getGCMRequest(String message, List registrationIds) { - JsonObject gcmRequest = new JsonObject(); - gcmRequest.addProperty("delay_while_idle", false); - gcmRequest.addProperty("time_to_live", TIME_TO_LIVE); + private static String getFCMRequest(String message, List registrationIds) { + JsonObject fcmRequest = new JsonObject(); + fcmRequest.addProperty("delay_while_idle", false); + fcmRequest.addProperty("time_to_live", TIME_TO_LIVE); - //Add message to GCM request + //Add message to FCM request JsonObject data = new JsonObject(); if (message != null && !message.isEmpty()) { data.addProperty("data", message); - gcmRequest.add("data", data); + fcmRequest.add("data", data); } //Set device reg-ids @@ -135,27 +135,27 @@ public class GCMUtil { regIds.add(new JsonPrimitive(regId)); } - gcmRequest.add("registration_ids", regIds); - return gcmRequest.toString(); + fcmRequest.add("registration_ids", regIds); + return fcmRequest.toString(); } - private static List getGCMTokens(List devices) { + private static List getFCMTokens(List devices) { List tokens = new ArrayList<>(devices.size()); for (Device device : devices) { - tokens.add(getGCMToken(device.getProperties())); + tokens.add(getFCMToken(device.getProperties())); } return tokens; } - private static String getGCMToken(List properties) { - String gcmToken = null; + private static String getFCMToken(List properties) { + String fcmToken = null; for (Device.Property property : properties) { - if (AndroidPluginConstants.GCM_TOKEN.equals(property.getName())) { - gcmToken = property.getValue(); + if (AndroidPluginConstants.FCM_TOKEN.equals(property.getName())) { + fcmToken = property.getValue(); break; } } - return gcmToken; + return fcmToken; } public static String getConfigurationProperty(String property) { diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/util/AndroidPluginConstants.java b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/util/AndroidPluginConstants.java index 3cea5588c..09b278e2c 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/util/AndroidPluginConstants.java +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/impl/util/AndroidPluginConstants.java @@ -25,7 +25,7 @@ public final class AndroidPluginConstants { //Properties related to AD_DEVICE table public static final String DEVICE_ID = "DEVICE_ID"; - public static final String GCM_TOKEN = "GCM_TOKEN"; + public static final String FCM_TOKEN = "FCM_TOKEN"; public static final String DEVICE_INFO = "DEVICE_INFO"; public static final String SERIAL = "SERIAL"; public static final String DEVICE_MODEL = "DEVICE_MODEL"; @@ -50,7 +50,7 @@ public final class AndroidPluginConstants { throw new AssertionError(); } - public static final String GCM = "GCM"; + public static final String FCM = "FCM"; public static final String LOCAL = "LOCAL"; } diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/internal/AndroidDeviceManagementDataHolder.java b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/internal/AndroidDeviceManagementDataHolder.java index ee4a7c021..028c6aeda 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/internal/AndroidDeviceManagementDataHolder.java +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/internal/AndroidDeviceManagementDataHolder.java @@ -19,7 +19,7 @@ package org.wso2.carbon.device.mgt.mobile.android.internal; import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService; -import org.wso2.carbon.device.mgt.mobile.android.impl.gcm.GCMService; +import org.wso2.carbon.device.mgt.mobile.android.impl.fcm.FCMService; import org.wso2.carbon.registry.core.service.RegistryService; /** @@ -29,7 +29,7 @@ public class AndroidDeviceManagementDataHolder { private RegistryService registryService; private DeviceManagementService androidDeviceManagementService; - private GCMService gcmService; + private FCMService fcmService; private static AndroidDeviceManagementDataHolder thisInstance = new AndroidDeviceManagementDataHolder(); @@ -57,11 +57,11 @@ public class AndroidDeviceManagementDataHolder { this.androidDeviceManagementService = androidDeviceManagementService; } - public GCMService getGCMService() { - return gcmService; + public FCMService getFCMService() { + return fcmService; } - public void setGCMService(GCMService gcmService) { - this.gcmService = gcmService; + public void setFCMService(FCMService fcmService) { + this.fcmService = fcmService; } } diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/internal/AndroidDeviceManagementServiceComponent.java b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/internal/AndroidDeviceManagementServiceComponent.java index 66e441ecb..c1ecae0a4 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/internal/AndroidDeviceManagementServiceComponent.java +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android/src/main/java/org/wso2/carbon/device/mgt/mobile/android/internal/AndroidDeviceManagementServiceComponent.java @@ -25,7 +25,7 @@ import org.osgi.framework.ServiceRegistration; import org.osgi.service.component.ComponentContext; import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService; import org.wso2.carbon.device.mgt.mobile.android.impl.AndroidDeviceManagementService; -import org.wso2.carbon.device.mgt.mobile.android.impl.gcm.GCMService; +import org.wso2.carbon.device.mgt.mobile.android.impl.fcm.FCMService; import org.wso2.carbon.ndatasource.core.DataSourceService; import org.wso2.carbon.registry.core.service.RegistryService; @@ -50,7 +50,7 @@ public class AndroidDeviceManagementServiceComponent { private static final Log log = LogFactory.getLog(AndroidDeviceManagementServiceComponent.class); private ServiceRegistration androidServiceRegRef; - private ServiceRegistration gcmServiceRegRef; + private ServiceRegistration fcmServiceRegRef; protected void activate(ComponentContext ctx) { @@ -61,14 +61,14 @@ public class AndroidDeviceManagementServiceComponent { BundleContext bundleContext = ctx.getBundleContext(); DeviceManagementService androidDeviceManagementService = new AndroidDeviceManagementService(); - GCMService gcmService = new GCMService(); + FCMService fcmService = new FCMService(); // androidServiceRegRef = // bundleContext.registerService(DeviceManagementService.class.getName(), // androidDeviceManagementService, null); - gcmServiceRegRef = - bundleContext.registerService(GCMService.class.getName(), gcmService, null); + fcmServiceRegRef = + bundleContext.registerService(FCMService.class.getName(), fcmService, null); // Policy management service @@ -78,7 +78,7 @@ public class AndroidDeviceManagementServiceComponent { AndroidDeviceManagementDataHolder.getInstance().setAndroidDeviceManagementService( androidDeviceManagementService); - AndroidDeviceManagementDataHolder.getInstance().setGCMService(gcmService); + AndroidDeviceManagementDataHolder.getInstance().setFCMService(fcmService); if (log.isDebugEnabled()) { log.debug("Android Mobile Device Management Service Component has been successfully activated"); @@ -96,8 +96,8 @@ public class AndroidDeviceManagementServiceComponent { if (androidServiceRegRef != null) { androidServiceRegRef.unregister(); } - if (gcmServiceRegRef != null) { - gcmServiceRegRef.unregister(); + if (fcmServiceRegRef != null) { + fcmServiceRegRef.unregister(); } if (log.isDebugEnabled()) { log.debug( diff --git a/components/mobile-plugins/android-plugin/pom.xml b/components/mobile-plugins/android-plugin/pom.xml index 2493fdc14..5e32bb7aa 100644 --- a/components/mobile-plugins/android-plugin/pom.xml +++ b/components/mobile-plugins/android-plugin/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.devicemgt-plugins mobile-plugins - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/mobile-plugins/pom.xml b/components/mobile-plugins/pom.xml index 4ce34b0f5..60b18aea6 100644 --- a/components/mobile-plugins/pom.xml +++ b/components/mobile-plugins/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.devicemgt-plugins carbon-device-mgt-plugins-parent - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../../pom.xml diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/pom.xml b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/pom.xml index f8537e1f9..833c32d6a 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/pom.xml +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/pom.xml @@ -21,7 +21,7 @@ windows-plugin org.wso2.carbon.devicemgt-plugins - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/ConfigurationMgtService.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/ConfigurationMgtService.java index 236d8d8a5..827dec630 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/ConfigurationMgtService.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/ConfigurationMgtService.java @@ -62,7 +62,7 @@ import javax.ws.rs.core.Response; } ), tags = { - @Tag(name = "windows", description = "") + @Tag(name = "windows,device_management", description = "") } ) @Api(value = "Windows Configuration Management", diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/DeviceManagementAdminService.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/DeviceManagementAdminService.java index b97f0e6dc..210946289 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/DeviceManagementAdminService.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/DeviceManagementAdminService.java @@ -55,7 +55,7 @@ import java.util.List; } ), tags = { - @Tag(name = "windows", description = "") + @Tag(name = "windows,device_management", description = "") } ) @Api(value = "Windows Device Management Administrative Service", diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/authbst/BSTProvider.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/authbst/BSTProvider.java index bb9e568f8..0fbb93df0 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/authbst/BSTProvider.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/authbst/BSTProvider.java @@ -51,7 +51,7 @@ import javax.ws.rs.core.Response; } ), tags = { - @Tag(name = "windows", description = "") + @Tag(name = "windows,device_management", description = "") } ) @Api(value = "Windows Binary Security Token Service", diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/webapp/WEB-INF/web.xml b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/webapp/WEB-INF/web.xml index 6ea6be132..d4d1c22e9 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/webapp/WEB-INF/web.xml +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/webapp/WEB-INF/web.xml @@ -56,6 +56,10 @@ doAuthentication true + + isSharedWithAllTenants + true + nonSecuredEndPoints /api/device-mgt/windows/v1.0/discovery/get,/api/device-mgt/windows/v1.0/discovery/post, diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/pom.xml b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/pom.xml index e979e3af3..9267ec6e1 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/pom.xml +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/pom.xml @@ -23,13 +23,13 @@ windows-plugin org.wso2.carbon.devicemgt-plugins - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT ../pom.xml 4.0.0 org.wso2.carbon.device.mgt.mobile.windows.ui - 3.0.12-SNAPSHOT + 3.0.15-SNAPSHOT WSO2 Carbon - Mobile Windows UI pom diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.operation-bar/public/templates/operations.hbs b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.operation-bar/public/templates/operations.hbs index 8e1c19dc4..2a96b1503 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.operation-bar/public/templates/operations.hbs +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.operation-bar/public/templates/operations.hbs @@ -1,7 +1,7 @@