From 28986756fd717f1762fb52dc8b32213fbb7cd377 Mon Sep 17 00:00:00 2001 From: kaviska Date: Fri, 17 Jul 2026 08:22:32 +0530 Subject: [PATCH 1/3] Introduce New Device Management API Endpoint --- .../pom.xml | 51 +++ .../server/device/mgt/common/Constants.java | 109 +++++++ .../mgt/common/DeviceMgtServiceHolder.java | 42 +++ .../pom.xml | 170 ++++++++++ .../api/server/device/mgt/v1/DevicesApi.java | 144 +++++++++ .../device/mgt/v1/DevicesApiService.java | 43 +++ .../factories/DevicesApiServiceFactory.java | 32 ++ .../device/mgt/v1/model/DeviceListLink.java | 121 +++++++ .../mgt/v1/model/DeviceListResponse.java | 209 ++++++++++++ .../mgt/v1/model/DevicePatchRequest.java | 101 ++++++ .../device/mgt/v1/model/DeviceResponse.java | 232 ++++++++++++++ .../api/server/device/mgt/v1/model/Error.java | 161 ++++++++++ .../v1/core/DeviceManagementApiService.java | 240 ++++++++++++++ .../v1/factories/DeviceServiceFactory.java | 52 +++ .../mgt/v1/impl/DevicesApiServiceImpl.java | 64 ++++ .../src/main/resources/device-mgt.yaml | 299 ++++++++++++++++++ .../pom.xml | 36 +++ pom.xml | 13 + 18 files changed, 2119 insertions(+) create mode 100644 components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.common/pom.xml create mode 100644 components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.common/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/common/Constants.java create mode 100644 components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.common/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/common/DeviceMgtServiceHolder.java create mode 100644 components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/pom.xml create mode 100644 components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/DevicesApi.java create mode 100644 components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/DevicesApiService.java create mode 100644 components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/factories/DevicesApiServiceFactory.java create mode 100644 components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/DeviceListLink.java create mode 100644 components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/DeviceListResponse.java create mode 100644 components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/DevicePatchRequest.java create mode 100644 components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/DeviceResponse.java create mode 100644 components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/Error.java create mode 100644 components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/v1/core/DeviceManagementApiService.java create mode 100644 components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/v1/factories/DeviceServiceFactory.java create mode 100644 components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/v1/impl/DevicesApiServiceImpl.java create mode 100644 components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/resources/device-mgt.yaml create mode 100644 components/org.wso2.carbon.identity.api.server.device.mgt/pom.xml diff --git a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.common/pom.xml b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.common/pom.xml new file mode 100644 index 0000000000..83a5b456cf --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.common/pom.xml @@ -0,0 +1,51 @@ + + + + 4.0.0 + + + org.wso2.carbon.identity.server.api + org.wso2.carbon.identity.api.server.device.mgt + 1.6.36-SNAPSHOT + + + org.wso2.carbon.identity.api.server.device.mgt.common + jar + + + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.device.mgt + provided + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + diff --git a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.common/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/common/Constants.java b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.common/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/common/Constants.java new file mode 100644 index 0000000000..dd7ac39090 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.common/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/common/Constants.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2026, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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.identity.api.server.device.mgt.common; + +/** + * Constants for the device management REST API. + */ +public class Constants { + + private Constants() { + } + + public static final String DEVICE_MGT_ERROR_PREFIX = "DM-"; + + public static final String V1_API_PATH_COMPONENT = "/v1"; + + public static final String DEVICE_PATH_COMPONENT = "/devices"; + + /** + * Error messages for the device management API. + */ + public enum ErrorMessage { + + ERROR_CODE_DEVICE_NOT_FOUND("60001", + "Device not found.", + "No device found for the given device id: %s."), + + ERROR_CODE_INVALID_PAGINATION("60101", + "Invalid pagination parameters.", + "The 'limit' must be greater than or equal to 1 and 'offset' must be greater than or equal to 0."), + + ERROR_CODE_INVALID_DEVICE_NAME("60102", + "Invalid device name.", + "Device name must be a non-blank string of at most 255 characters."), + + ERROR_CODE_ERROR_LISTING_DEVICES("65101", + "Unable to list devices.", + "Server encountered an error while listing devices."), + + ERROR_CODE_ERROR_RETRIEVING_DEVICE("65102", + "Unable to retrieve device.", + "Server encountered an error while retrieving the device."), + + ERROR_CODE_ERROR_UPDATING_DEVICE("65103", + "Unable to update device.", + "Server encountered an error while updating the device."), + + ERROR_CODE_ERROR_DELETING_DEVICE("65104", + "Unable to delete device.", + "Server encountered an error while deleting the device."); + + private final String code; + private final String message; + private final String description; + + ErrorMessage(String code, String message, String description) { + + this.code = code; + this.message = message; + this.description = description; + } + + /** + * Returns the error code with prefix. + * + * @return Error code. + */ + public String code() { + + return DEVICE_MGT_ERROR_PREFIX + code; + } + + /** + * Returns the error message. + * + * @return Error message. + */ + public String message() { + + return message; + } + + /** + * Returns the error description. + * + * @return Error description. + */ + public String description() { + + return description; + } + } +} diff --git a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.common/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/common/DeviceMgtServiceHolder.java b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.common/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/common/DeviceMgtServiceHolder.java new file mode 100644 index 0000000000..6e9b18b52e --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.common/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/common/DeviceMgtServiceHolder.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2026, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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.identity.api.server.device.mgt.common; + +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.identity.device.mgt.api.service.DeviceManagementService; + +/** + * Service holder for device management API — retrieves OSGi services from the Carbon context. + */ +public class DeviceMgtServiceHolder { + + private DeviceMgtServiceHolder() { + } + + /** + * Returns the DeviceManagementService OSGi service. + * + * @return DeviceManagementService instance. + */ + public static DeviceManagementService getDeviceManagementService() { + + return (DeviceManagementService) PrivilegedCarbonContext + .getThreadLocalCarbonContext().getOSGiService(DeviceManagementService.class, null); + } +} diff --git a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/pom.xml b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/pom.xml new file mode 100644 index 0000000000..08b82b2329 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/pom.xml @@ -0,0 +1,170 @@ + + + + 4.0.0 + + + org.wso2.carbon.identity.server.api + org.wso2.carbon.identity.api.server.device.mgt + 1.6.36-SNAPSHOT + + + org.wso2.carbon.identity.api.server.device.mgt.v1 + jar + + + + org.apache.cxf + cxf-rt-frontend-jaxrs + provided + + + org.apache.cxf + cxf-rt-rs-service-description + provided + + + javax.ws.rs + javax.ws.rs-api + provided + + + io.swagger + swagger-jaxrs + + + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.core + jackson-annotations + + + com.fasterxml.jackson.core + jackson-core + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + + + javax.ws.rs + jsr311-api + + + com.google.guava + guava + + + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider + provided + + + org.wso2.carbon.identity.server.api + org.wso2.carbon.identity.api.server.common + provided + + + org.wso2.carbon.identity.server.api + org.wso2.carbon.identity.api.server.device.mgt.common + provided + + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.device.mgt + provided + + + commons-lang.wso2 + commons-lang + 2.6.0.wso2v1 + compile + + + + + + + org.openapitools + openapi-generator-maven-plugin + 4.1.2 + + + + generate + + + ${project.basedir}/src/main/resources/device-mgt.yaml + org.wso2.carbon.codegen.CxfWso2Generator + + src/gen/java + org.wso2.carbon.identity.api.server.device.mgt.v1 + org.wso2.carbon.identity.api.server.device.mgt.v1.model + org.wso2.carbon.identity.api.server.device.mgt.v1 + java8 + true + + . + false + + + + + + org.openapitools + cxf-wso2-openapi-generator + 1.0.0 + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.8 + + + add-source + generate-sources + + add-source + + + + src/gen/java + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven.compiler.plugin.version} + + 1.8 + 1.8 + + + + + diff --git a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/DevicesApi.java b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/DevicesApi.java new file mode 100644 index 0000000000..ef99888274 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/DevicesApi.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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.identity.api.server.device.mgt.v1; + +import org.apache.cxf.jaxrs.ext.multipart.Attachment; +import org.apache.cxf.jaxrs.ext.multipart.Multipart; +import java.io.InputStream; +import java.util.List; + +import org.wso2.carbon.identity.api.server.device.mgt.v1.model.DeviceListResponse; +import org.wso2.carbon.identity.api.server.device.mgt.v1.model.DevicePatchRequest; +import org.wso2.carbon.identity.api.server.device.mgt.v1.model.DeviceResponse; +import org.wso2.carbon.identity.api.server.device.mgt.v1.model.Error; +import org.wso2.carbon.identity.api.server.device.mgt.v1.DevicesApiService; +import org.wso2.carbon.identity.api.server.device.mgt.v1.factories.DevicesApiServiceFactory; + +import javax.validation.Valid; +import javax.ws.rs.*; +import javax.ws.rs.core.Response; +import io.swagger.annotations.*; + +import javax.validation.constraints.*; + +@Path("/devices") +@Api(description = "The devices API") + +public class DevicesApi { + + private final DevicesApiService delegate; + + public DevicesApi() { + + this.delegate = DevicesApiServiceFactory.getDevicesApi(); + } + + @Valid + @DELETE + @Path("/{device-id}") + + @Produces({ "application/json" }) + @ApiOperation(value = "Delete a registered device.", notes = "This API provides the capability to delete a registered device by its ID. Scope (Permission) required: ``internal_device_mgt_delete`` ", response = Void.class, authorizations = { + @Authorization(value = "BasicAuth"), + @Authorization(value = "OAuth2", scopes = { + + }) + }, tags={ "Device Management", }) + @ApiResponses(value = { + @ApiResponse(code = 204, message = "Successfully Deleted", response = Void.class), + @ApiResponse(code = 401, message = "Unauthorized", response = Void.class), + @ApiResponse(code = 403, message = "Forbidden", response = Void.class), + @ApiResponse(code = 404, message = "Not Found", response = Error.class), + @ApiResponse(code = 500, message = "Server Error", response = Error.class) + }) + public Response deleteDevice(@ApiParam(value = "UUID of the registered device",required=true) @PathParam("device-id") String deviceId) { + + return delegate.deleteDevice(deviceId ); + } + + @Valid + @GET + @Path("/{device-id}") + + @Produces({ "application/json" }) + @ApiOperation(value = "Get a registered device by ID.", notes = "This API provides the capability to retrieve a registered device by its ID. Scope (Permission) required: ``internal_device_mgt_view`` ", response = DeviceResponse.class, authorizations = { + @Authorization(value = "BasicAuth"), + @Authorization(value = "OAuth2", scopes = { + + }) + }, tags={ "Device Management", }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Successful Response", response = DeviceResponse.class), + @ApiResponse(code = 401, message = "Unauthorized", response = Void.class), + @ApiResponse(code = 403, message = "Forbidden", response = Void.class), + @ApiResponse(code = 404, message = "Not Found", response = Error.class), + @ApiResponse(code = 500, message = "Server Error", response = Error.class) + }) + public Response getDevice(@ApiParam(value = "UUID of the registered device",required=true) @PathParam("device-id") String deviceId) { + + return delegate.getDevice(deviceId ); + } + + @Valid + @GET + + + @Produces({ "application/json" }) + @ApiOperation(value = "List all registered devices in the tenant.", notes = "This API provides the capability to list a paginated set of registered devices for the tenant. Scope (Permission) required: ``internal_device_mgt_view`` ", response = DeviceListResponse.class, authorizations = { + @Authorization(value = "BasicAuth"), + @Authorization(value = "OAuth2", scopes = { + + }) + }, tags={ "Device Management", }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Successful Response", response = DeviceListResponse.class), + @ApiResponse(code = 401, message = "Unauthorized", response = Void.class), + @ApiResponse(code = 403, message = "Forbidden", response = Void.class), + @ApiResponse(code = 500, message = "Server Error", response = Error.class) + }) + public Response listDevices( @Valid @Min(1)@ApiParam(value = "Maximum number of records to return.", defaultValue="30") @DefaultValue("30") @QueryParam("limit") Integer limit, @Valid @Min(0)@ApiParam(value = "Number of records to skip for pagination.", defaultValue="0") @DefaultValue("0") @QueryParam("offset") Integer offset, @Valid@ApiParam(value = "Filter devices by the ID of the user who registered them. Returns devices of any status. Pagination applies as usual.") @QueryParam("userId") String userId) { + + return delegate.listDevices(limit, offset, userId ); + } + + @Valid + @PATCH + @Path("/{device-id}") + @Consumes({ "application/json" }) + @Produces({ "application/json" }) + @ApiOperation(value = "Rename a registered device.", notes = "This API provides the capability to update the display name of a registered device. Scope (Permission) required: ``internal_device_mgt_update`` ", response = DeviceResponse.class, authorizations = { + @Authorization(value = "BasicAuth"), + @Authorization(value = "OAuth2", scopes = { + + }) + }, tags={ "Device Management" }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Successful Response", response = DeviceResponse.class), + @ApiResponse(code = 400, message = "Bad Request", response = Error.class), + @ApiResponse(code = 401, message = "Unauthorized", response = Void.class), + @ApiResponse(code = 403, message = "Forbidden", response = Void.class), + @ApiResponse(code = 404, message = "Not Found", response = Error.class), + @ApiResponse(code = 500, message = "Server Error", response = Error.class) + }) + public Response updateDeviceName(@ApiParam(value = "UUID of the registered device",required=true) @PathParam("device-id") String deviceId, @ApiParam(value = "" ,required=true) @Valid DevicePatchRequest devicePatchRequest) { + + return delegate.updateDeviceName(deviceId, devicePatchRequest ); + } + +} diff --git a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/DevicesApiService.java b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/DevicesApiService.java new file mode 100644 index 0000000000..a3b5f70e5b --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/DevicesApiService.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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.identity.api.server.device.mgt.v1; + +import org.wso2.carbon.identity.api.server.device.mgt.v1.*; +import org.wso2.carbon.identity.api.server.device.mgt.v1.model.*; +import org.apache.cxf.jaxrs.ext.multipart.Attachment; +import org.apache.cxf.jaxrs.ext.multipart.Multipart; +import java.io.InputStream; +import java.util.List; +import org.wso2.carbon.identity.api.server.device.mgt.v1.model.DeviceListResponse; +import org.wso2.carbon.identity.api.server.device.mgt.v1.model.DevicePatchRequest; +import org.wso2.carbon.identity.api.server.device.mgt.v1.model.DeviceResponse; +import org.wso2.carbon.identity.api.server.device.mgt.v1.model.Error; +import javax.ws.rs.core.Response; + + +public interface DevicesApiService { + + public Response deleteDevice(String deviceId); + + public Response getDevice(String deviceId); + + public Response listDevices(Integer limit, Integer offset, String userId); + + public Response updateDeviceName(String deviceId, DevicePatchRequest devicePatchRequest); +} diff --git a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/factories/DevicesApiServiceFactory.java b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/factories/DevicesApiServiceFactory.java new file mode 100644 index 0000000000..92e9489e90 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/factories/DevicesApiServiceFactory.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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.identity.api.server.device.mgt.v1.factories; + +import org.wso2.carbon.identity.api.server.device.mgt.v1.DevicesApiService; +import org.wso2.carbon.identity.api.server.device.mgt.v1.impl.DevicesApiServiceImpl; + +public class DevicesApiServiceFactory { + + private final static DevicesApiService SERVICE = new DevicesApiServiceImpl(); + + public static DevicesApiService getDevicesApi() { + + return SERVICE; + } +} diff --git a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/DeviceListLink.java b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/DeviceListLink.java new file mode 100644 index 0000000000..0df8bfb030 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/DeviceListLink.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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.identity.api.server.device.mgt.v1.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class DeviceListLink { + + private String href; + private String rel; + + /** + * Relative URL to the linked page. + **/ + public DeviceListLink href(String href) { + + this.href = href; + return this; + } + + @ApiModelProperty(example = "/t/carbon.super/api/server/v1/devices?offset=10&limit=10", value = "Relative URL to the linked page.") + @JsonProperty("href") + @Valid + public String getHref() { + return href; + } + public void setHref(String href) { + this.href = href; + } + + /** + * Relation to the current page. + **/ + public DeviceListLink rel(String rel) { + + this.rel = rel; + return this; + } + + @ApiModelProperty(example = "next", value = "Relation to the current page.") + @JsonProperty("rel") + @Valid + public String getRel() { + return rel; + } + public void setRel(String rel) { + this.rel = rel; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + DeviceListLink deviceListLink = (DeviceListLink) o; + return Objects.equals(this.href, deviceListLink.href) && + Objects.equals(this.rel, deviceListLink.rel); + } + + @Override + public int hashCode() { + return Objects.hash(href, rel); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class DeviceListLink {\n"); + + sb.append(" href: ").append(toIndentedString(href)).append("\n"); + sb.append(" rel: ").append(toIndentedString(rel)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n"); + } +} + diff --git a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/DeviceListResponse.java b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/DeviceListResponse.java new file mode 100644 index 0000000000..144364ced8 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/DeviceListResponse.java @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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.identity.api.server.device.mgt.v1.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import org.wso2.carbon.identity.api.server.device.mgt.v1.model.DeviceListLink; +import org.wso2.carbon.identity.api.server.device.mgt.v1.model.DeviceResponse; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class DeviceListResponse { + + private Integer totalResults; + private Integer startIndex; + private Integer count; + private List devices = null; + + private List links = null; + + + /** + * Number of results that match the listing operation. + **/ + public DeviceListResponse totalResults(Integer totalResults) { + + this.totalResults = totalResults; + return this; + } + + @ApiModelProperty(example = "42", value = "Number of results that match the listing operation.") + @JsonProperty("totalResults") + @Valid + public Integer getTotalResults() { + return totalResults; + } + public void setTotalResults(Integer totalResults) { + this.totalResults = totalResults; + } + + /** + * Index of the first element of the page, which will be equal to offset + 1. + **/ + public DeviceListResponse startIndex(Integer startIndex) { + + this.startIndex = startIndex; + return this; + } + + @ApiModelProperty(example = "1", value = "Index of the first element of the page, which will be equal to offset + 1.") + @JsonProperty("startIndex") + @Valid + public Integer getStartIndex() { + return startIndex; + } + public void setStartIndex(Integer startIndex) { + this.startIndex = startIndex; + } + + /** + * Number of elements in the returned page. + **/ + public DeviceListResponse count(Integer count) { + + this.count = count; + return this; + } + + @ApiModelProperty(example = "10", value = "Number of elements in the returned page.") + @JsonProperty("count") + @Valid + public Integer getCount() { + return count; + } + public void setCount(Integer count) { + this.count = count; + } + + /** + * Page of registered devices. + **/ + public DeviceListResponse devices(List devices) { + + this.devices = devices; + return this; + } + + @ApiModelProperty(value = "Page of registered devices.") + @JsonProperty("devices") + @Valid + public List getDevices() { + return devices; + } + public void setDevices(List devices) { + this.devices = devices; + } + + public DeviceListResponse addDevicesItem(DeviceResponse devicesItem) { + if (this.devices == null) { + this.devices = new ArrayList<>(); + } + this.devices.add(devicesItem); + return this; + } + + /** + * Pagination links (next/previous). + **/ + public DeviceListResponse links(List links) { + + this.links = links; + return this; + } + + @ApiModelProperty(value = "Pagination links (next/previous).") + @JsonProperty("links") + @Valid + public List getLinks() { + return links; + } + public void setLinks(List links) { + this.links = links; + } + + public DeviceListResponse addLinksItem(DeviceListLink linksItem) { + if (this.links == null) { + this.links = new ArrayList<>(); + } + this.links.add(linksItem); + return this; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + DeviceListResponse deviceListResponse = (DeviceListResponse) o; + return Objects.equals(this.totalResults, deviceListResponse.totalResults) && + Objects.equals(this.startIndex, deviceListResponse.startIndex) && + Objects.equals(this.count, deviceListResponse.count) && + Objects.equals(this.devices, deviceListResponse.devices) && + Objects.equals(this.links, deviceListResponse.links); + } + + @Override + public int hashCode() { + return Objects.hash(totalResults, startIndex, count, devices, links); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class DeviceListResponse {\n"); + + sb.append(" totalResults: ").append(toIndentedString(totalResults)).append("\n"); + sb.append(" startIndex: ").append(toIndentedString(startIndex)).append("\n"); + sb.append(" count: ").append(toIndentedString(count)).append("\n"); + sb.append(" devices: ").append(toIndentedString(devices)).append("\n"); + sb.append(" links: ").append(toIndentedString(links)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n"); + } +} + diff --git a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/DevicePatchRequest.java b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/DevicePatchRequest.java new file mode 100644 index 0000000000..5109048f86 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/DevicePatchRequest.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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.identity.api.server.device.mgt.v1.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class DevicePatchRequest { + + private String deviceName; + + /** + * The new display name for the device. + **/ + public DevicePatchRequest deviceName(String deviceName) { + + this.deviceName = deviceName; + return this; + } + + @ApiModelProperty(example = "My Work Phone", required = true, value = "The new display name for the device.") + @JsonProperty("deviceName") + @Valid + @NotNull(message = "Property deviceName cannot be null.") + @Size(min=1,max=255) + public String getDeviceName() { + return deviceName; + } + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + DevicePatchRequest devicePatchRequest = (DevicePatchRequest) o; + return Objects.equals(this.deviceName, devicePatchRequest.deviceName); + } + + @Override + public int hashCode() { + return Objects.hash(deviceName); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class DevicePatchRequest {\n"); + + sb.append(" deviceName: ").append(toIndentedString(deviceName)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n"); + } +} + diff --git a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/DeviceResponse.java b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/DeviceResponse.java new file mode 100644 index 0000000000..f975e58f3b --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/DeviceResponse.java @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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.identity.api.server.device.mgt.v1.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.time.OffsetDateTime; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class DeviceResponse { + + private String id; + private String userId; + private String deviceName; + private String deviceModel; + private String status; + private OffsetDateTime registeredAt; + private String metadata; + + /** + * The device UUID. + **/ + public DeviceResponse id(String id) { + + this.id = id; + return this; + } + + @ApiModelProperty(example = "74070bae-df8c-42bf-8754-5173c237c936", value = "The device UUID.") + @JsonProperty("id") + @Valid + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + + /** + * The user identifier who owns the device. + **/ + public DeviceResponse userId(String userId) { + + this.userId = userId; + return this; + } + + @ApiModelProperty(example = "kaviska", value = "The user identifier who owns the device.") + @JsonProperty("userId") + @Valid + public String getUserId() { + return userId; + } + public void setUserId(String userId) { + this.userId = userId; + } + + /** + * The display name of the device. + **/ + public DeviceResponse deviceName(String deviceName) { + + this.deviceName = deviceName; + return this; + } + + @ApiModelProperty(example = "My iPhone", value = "The display name of the device.") + @JsonProperty("deviceName") + @Valid + public String getDeviceName() { + return deviceName; + } + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + /** + * The hardware model of the device. + **/ + public DeviceResponse deviceModel(String deviceModel) { + + this.deviceModel = deviceModel; + return this; + } + + @ApiModelProperty(example = "iPhone 15 Pro", value = "The hardware model of the device.") + @JsonProperty("deviceModel") + @Valid + public String getDeviceModel() { + return deviceModel; + } + public void setDeviceModel(String deviceModel) { + this.deviceModel = deviceModel; + } + + /** + * The current device status. + **/ + public DeviceResponse status(String status) { + + this.status = status; + return this; + } + + @ApiModelProperty(example = "ACTIVE", value = "The current device status.") + @JsonProperty("status") + @Valid + public String getStatus() { + return status; + } + public void setStatus(String status) { + this.status = status; + } + + /** + * The timestamp when the device was registered. + **/ + public DeviceResponse registeredAt(OffsetDateTime registeredAt) { + + this.registeredAt = registeredAt; + return this; + } + + @ApiModelProperty(example = "2026-04-27T10:00Z", value = "The timestamp when the device was registered.") + @JsonProperty("registeredAt") + @Valid + public OffsetDateTime getRegisteredAt() { + return registeredAt; + } + public void setRegisteredAt(OffsetDateTime registeredAt) { + this.registeredAt = registeredAt; + } + + /** + * Additional non-sensitive metadata associated with the device. + **/ + public DeviceResponse metadata(String metadata) { + + this.metadata = metadata; + return this; + } + + @ApiModelProperty(example = "{\"osVersion\":\"17.0\",\"deviceType\":\"mobile\",\"manufacturer\":\"Apple\"}", value = "Additional non-sensitive metadata associated with the device.") + @JsonProperty("metadata") + @Valid + public String getMetadata() { + return metadata; + } + public void setMetadata(String metadata) { + this.metadata = metadata; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + DeviceResponse deviceResponse = (DeviceResponse) o; + return Objects.equals(this.id, deviceResponse.id) && + Objects.equals(this.userId, deviceResponse.userId) && + Objects.equals(this.deviceName, deviceResponse.deviceName) && + Objects.equals(this.deviceModel, deviceResponse.deviceModel) && + Objects.equals(this.status, deviceResponse.status) && + Objects.equals(this.registeredAt, deviceResponse.registeredAt) && + Objects.equals(this.metadata, deviceResponse.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(id, userId, deviceName, deviceModel, status, registeredAt, metadata); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class DeviceResponse {\n"); + + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" userId: ").append(toIndentedString(userId)).append("\n"); + sb.append(" deviceName: ").append(toIndentedString(deviceName)).append("\n"); + sb.append(" deviceModel: ").append(toIndentedString(deviceModel)).append("\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append(" registeredAt: ").append(toIndentedString(registeredAt)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n"); + } +} + diff --git a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/Error.java b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/Error.java new file mode 100644 index 0000000000..c6eabf3cad --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/Error.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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.identity.api.server.device.mgt.v1.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; +import javax.validation.Valid; +import javax.xml.bind.annotation.*; + +public class Error { + + private String code; + private String message; + private String description; + private String traceId; + + /** + **/ + public Error code(String code) { + + this.code = code; + return this; + } + + @ApiModelProperty(example = "DM-60001", value = "") + @JsonProperty("code") + @Valid + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + + /** + **/ + public Error message(String message) { + + this.message = message; + return this; + } + + @ApiModelProperty(example = "Some Error Message.", value = "") + @JsonProperty("message") + @Valid + public String getMessage() { + return message; + } + public void setMessage(String message) { + this.message = message; + } + + /** + **/ + public Error description(String description) { + + this.description = description; + return this; + } + + @ApiModelProperty(example = "Some Error Description.", value = "") + @JsonProperty("description") + @Valid + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + /** + **/ + public Error traceId(String traceId) { + + this.traceId = traceId; + return this; + } + + @ApiModelProperty(example = "e0fbcfeb-3617-43c4-8dd0-7b7d38e13047", value = "") + @JsonProperty("traceId") + @Valid + public String getTraceId() { + return traceId; + } + public void setTraceId(String traceId) { + this.traceId = traceId; + } + + + + @Override + public boolean equals(java.lang.Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Error error = (Error) o; + return Objects.equals(this.code, error.code) && + Objects.equals(this.message, error.message) && + Objects.equals(this.description, error.description) && + Objects.equals(this.traceId, error.traceId); + } + + @Override + public int hashCode() { + return Objects.hash(code, message, description, traceId); + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + sb.append("class Error {\n"); + + sb.append(" code: ").append(toIndentedString(code)).append("\n"); + sb.append(" message: ").append(toIndentedString(message)).append("\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); + sb.append(" traceId: ").append(toIndentedString(traceId)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n"); + } +} + diff --git a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/v1/core/DeviceManagementApiService.java b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/v1/core/DeviceManagementApiService.java new file mode 100644 index 0000000000..ea4f3a5578 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/v1/core/DeviceManagementApiService.java @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2026, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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.identity.api.server.device.mgt.v1.core; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.identity.api.server.common.ContextLoader; +import org.wso2.carbon.identity.api.server.common.Util; +import org.wso2.carbon.identity.api.server.common.error.APIError; +import org.wso2.carbon.identity.api.server.common.error.ErrorResponse; +import org.wso2.carbon.identity.api.server.device.mgt.common.Constants; +import org.wso2.carbon.identity.api.server.device.mgt.v1.model.DeviceListLink; +import org.wso2.carbon.identity.api.server.device.mgt.v1.model.DeviceListResponse; +import org.wso2.carbon.identity.api.server.device.mgt.v1.model.DevicePatchRequest; +import org.wso2.carbon.identity.api.server.device.mgt.v1.model.DeviceResponse; +import org.wso2.carbon.identity.device.mgt.api.constant.ErrorMessage; +import org.wso2.carbon.identity.device.mgt.api.exception.DeviceMgtClientException; +import org.wso2.carbon.identity.device.mgt.api.exception.DeviceMgtException; +import org.wso2.carbon.identity.device.mgt.api.model.Device; +import org.wso2.carbon.identity.device.mgt.api.service.DeviceManagementService; + +import java.time.OffsetDateTime; +import java.time.ZoneOffset; +import java.util.List; +import java.util.stream.Collectors; +import javax.ws.rs.core.Response; + +/** + * Core service for Device Management API — handles listing, renaming and deleting devices. + */ +public class DeviceManagementApiService { + + private static final Log LOG = LogFactory.getLog(DeviceManagementApiService.class); + private static final int DEFAULT_LIMIT = 30; + private static final int DEFAULT_OFFSET = 0; + private static final int DEVICE_NAME_MAX_LENGTH = 255; + + private final DeviceManagementService deviceManagementService; + + public DeviceManagementApiService(DeviceManagementService deviceManagementService) { + + this.deviceManagementService = deviceManagementService; + } + + /** + * Returns a paginated set of devices registered in the tenant, optionally filtered to a + * single user's devices. Returns devices of any status (ACTIVE or INACTIVE). + * + * @param limit Maximum number of records to return (defaults to 30 when null). + * @param offset Number of records to skip (defaults to 0 when null). + * @param userId ID of the user to filter devices by, or {@code null}/blank for no filtering. + * @return Paginated device list response. + */ + public DeviceListResponse listDevices(Integer limit, Integer offset, String userId) { + + int resolvedLimit = limit != null ? limit : DEFAULT_LIMIT; + int resolvedOffset = offset != null ? offset : DEFAULT_OFFSET; + String resolvedUserId = StringUtils.isNotBlank(userId) ? userId : null; + validatePaginationParameters(resolvedLimit, resolvedOffset); + + try { + String tenantDomain = ContextLoader.getTenantDomainFromContext(); + int totalResults = deviceManagementService.getDeviceCount(tenantDomain, resolvedUserId); + List devices = deviceManagementService.getDevices( + tenantDomain, resolvedOffset, resolvedLimit, resolvedUserId); + + List items = devices.stream() + .map(this::toDeviceResponse) + .collect(Collectors.toList()); + + List links = Util.buildPaginationLinks( + resolvedLimit, resolvedOffset, totalResults, Constants.DEVICE_PATH_COMPONENT) + .entrySet().stream() + .map(link -> new DeviceListLink().rel(link.getKey()).href(link.getValue())) + .collect(Collectors.toList()); + + return new DeviceListResponse() + .totalResults(totalResults) + .startIndex(resolvedOffset + 1) + .count(items.size()) + .devices(items) + .links(links); + } catch (DeviceMgtException e) { + throw handleException(e, Constants.ErrorMessage.ERROR_CODE_ERROR_LISTING_DEVICES, null); + } + } + + private void validatePaginationParameters(int limit, int offset) { + + if (limit < 1 || offset < 0) { + throw new APIError(Response.Status.BAD_REQUEST, new ErrorResponse.Builder() + .withCode(Constants.ErrorMessage.ERROR_CODE_INVALID_PAGINATION.code()) + .withMessage(Constants.ErrorMessage.ERROR_CODE_INVALID_PAGINATION.message()) + .withDescription(Constants.ErrorMessage.ERROR_CODE_INVALID_PAGINATION.description()) + .build(LOG, "Invalid pagination parameters.")); + } + } + + /** + * Returns a single device by ID. + * + * @param deviceId Device UUID. + * @return DeviceResponse. + */ + public DeviceResponse getDevice(String deviceId) { + + try { + String tenantDomain = ContextLoader.getTenantDomainFromContext(); + Device device = deviceManagementService.getDeviceById(deviceId, tenantDomain); + if (device == null) { + throw new APIError(Response.Status.NOT_FOUND, new ErrorResponse.Builder() + .withCode(Constants.ErrorMessage.ERROR_CODE_DEVICE_NOT_FOUND.code()) + .withMessage(Constants.ErrorMessage.ERROR_CODE_DEVICE_NOT_FOUND.message()) + .withDescription(String.format( + Constants.ErrorMessage.ERROR_CODE_DEVICE_NOT_FOUND.description(), deviceId)) + .build(LOG, "Device not found for id: " + deviceId)); + } + return toDeviceResponse(device); + } catch (DeviceMgtException e) { + throw handleException(e, Constants.ErrorMessage.ERROR_CODE_ERROR_RETRIEVING_DEVICE, deviceId); + } + } + + /** + * Updates the display name of a device. + * + * @param deviceId Device UUID. + * @param patchRequest Request body containing the new name. + * @return Updated DeviceResponse. + */ + public DeviceResponse updateDeviceName(String deviceId, DevicePatchRequest patchRequest) { + + validateDeviceName(patchRequest); + + try { + String tenantDomain = ContextLoader.getTenantDomainFromContext(); + Device updated = deviceManagementService.updateDeviceName( + deviceId, patchRequest.getDeviceName(), tenantDomain); + return toDeviceResponse(updated); + } catch (DeviceMgtException e) { + throw handleException(e, Constants.ErrorMessage.ERROR_CODE_ERROR_UPDATING_DEVICE, deviceId); + } + } + + private void validateDeviceName(DevicePatchRequest patchRequest) { + + String deviceName = patchRequest != null ? patchRequest.getDeviceName() : null; + if (StringUtils.isBlank(deviceName) || deviceName.length() > DEVICE_NAME_MAX_LENGTH) { + throw new APIError(Response.Status.BAD_REQUEST, new ErrorResponse.Builder() + .withCode(Constants.ErrorMessage.ERROR_CODE_INVALID_DEVICE_NAME.code()) + .withMessage(Constants.ErrorMessage.ERROR_CODE_INVALID_DEVICE_NAME.message()) + .withDescription(Constants.ErrorMessage.ERROR_CODE_INVALID_DEVICE_NAME.description()) + .build(LOG, "Invalid device name.")); + } + } + + /** + * Deletes a device by ID. + * + * @param deviceId Device UUID. + */ + public void deleteDevice(String deviceId) { + + try { + String tenantDomain = ContextLoader.getTenantDomainFromContext(); + deviceManagementService.deleteDevice(deviceId, tenantDomain); + } catch (DeviceMgtException e) { + throw handleException(e, Constants.ErrorMessage.ERROR_CODE_ERROR_DELETING_DEVICE, deviceId); + } + } + + private DeviceResponse toDeviceResponse(Device device) { + + DeviceResponse response = new DeviceResponse(); + response.setId(device.getId()); + response.setUserId(device.getUserId()); + response.setDeviceName(device.getDeviceName()); + response.setDeviceModel(device.getDeviceModel()); + if (device.getStatus() != null) { + response.setStatus(device.getStatus().name()); + } + if (device.getRegisteredAt() != null) { + response.setRegisteredAt( + OffsetDateTime.ofInstant(device.getRegisteredAt().toInstant(), ZoneOffset.UTC)); + } + response.setMetadata(device.getMetadata()); + return response; + } + + private APIError handleException(DeviceMgtException e, Constants.ErrorMessage errorEnum, String data) { + + ErrorResponse errorResponse; + Response.Status status; + + if (e instanceof DeviceMgtClientException) { + String backendErrorCode = e.getErrorCode(); + String errorCode; + if (backendErrorCode == null) { + errorCode = errorEnum.code(); + } else if (backendErrorCode.startsWith(Constants.DEVICE_MGT_ERROR_PREFIX)) { + errorCode = backendErrorCode; + } else { + errorCode = Constants.DEVICE_MGT_ERROR_PREFIX + backendErrorCode; + } + errorResponse = new ErrorResponse.Builder() + .withCode(errorCode) + .withMessage(e.getMessage()) + .withDescription(e.getDescription()) + .build(LOG, e.getMessage()); + status = ErrorMessage.ERROR_DEVICE_NOT_FOUND.getCode().equals(e.getErrorCode()) + ? Response.Status.NOT_FOUND + : Response.Status.BAD_REQUEST; + } else { + errorResponse = new ErrorResponse.Builder() + .withCode(errorEnum.code()) + .withMessage(errorEnum.message()) + .withDescription(errorEnum.description()) + .build(LOG, e, errorEnum.description()); + status = Response.Status.INTERNAL_SERVER_ERROR; + } + return new APIError(status, errorResponse); + } +} diff --git a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/v1/factories/DeviceServiceFactory.java b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/v1/factories/DeviceServiceFactory.java new file mode 100644 index 0000000000..f2082ed14a --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/v1/factories/DeviceServiceFactory.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2026, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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.identity.api.server.device.mgt.v1.factories; + +import org.wso2.carbon.identity.api.server.device.mgt.common.DeviceMgtServiceHolder; +import org.wso2.carbon.identity.api.server.device.mgt.v1.core.DeviceManagementApiService; +import org.wso2.carbon.identity.device.mgt.api.service.DeviceManagementService; + +/** + * Factory class for DeviceManagementApiService. + * Gets the OSGi service from ServiceHolder and injects it into DeviceManagementApiService. + * Created once at startup — singleton pattern using static initializer. + */ +public class DeviceServiceFactory { + + private static final DeviceManagementApiService SERVICE; + + static { + DeviceManagementService deviceManagementService = + DeviceMgtServiceHolder.getDeviceManagementService(); + + if (deviceManagementService == null) { + throw new IllegalStateException("DeviceManagementService is not available from OSGi context."); + } + + SERVICE = new DeviceManagementApiService(deviceManagementService); + } + + private DeviceServiceFactory() { + } + + public static DeviceManagementApiService getDeviceManagementApiService() { + + return SERVICE; + } +} diff --git a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/v1/impl/DevicesApiServiceImpl.java b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/v1/impl/DevicesApiServiceImpl.java new file mode 100644 index 0000000000..b80be418f5 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/v1/impl/DevicesApiServiceImpl.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2026, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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.identity.api.server.device.mgt.v1.impl; + +import org.wso2.carbon.identity.api.server.device.mgt.v1.DevicesApiService; +import org.wso2.carbon.identity.api.server.device.mgt.v1.core.DeviceManagementApiService; +import org.wso2.carbon.identity.api.server.device.mgt.v1.factories.DeviceServiceFactory; +import org.wso2.carbon.identity.api.server.device.mgt.v1.model.DevicePatchRequest; + +import javax.ws.rs.core.Response; + +/** + * JAX-RS delegate implementation — bridges generated DevicesApiService to the core service. + */ +public class DevicesApiServiceImpl implements DevicesApiService { + + private final DeviceManagementApiService service; + + public DevicesApiServiceImpl() { + + this.service = DeviceServiceFactory.getDeviceManagementApiService(); + } + + @Override + public Response listDevices(Integer limit, Integer offset, String userId) { + + return Response.ok().entity(service.listDevices(limit, offset, userId)).build(); + } + + @Override + public Response getDevice(String deviceId) { + + return Response.ok().entity(service.getDevice(deviceId)).build(); + } + + @Override + public Response updateDeviceName(String deviceId, DevicePatchRequest patchRequest) { + + return Response.ok().entity(service.updateDeviceName(deviceId, patchRequest)).build(); + } + + @Override + public Response deleteDevice(String deviceId) { + + service.deleteDevice(deviceId); + return Response.noContent().build(); + } +} diff --git a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/resources/device-mgt.yaml b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/resources/device-mgt.yaml new file mode 100644 index 0000000000..c0451ad326 --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/resources/device-mgt.yaml @@ -0,0 +1,299 @@ +openapi: 3.0.0 +info: + version: "1.0.0" + title: 'WSO2 Identity Server - Device Management API' + description: 'This document specifies a RESTful API for WSO2 Identity Server Device Management' + contact: + name: WSO2 + url: 'http://wso2.com/products/identity-server/' + email: architecture@wso2.org + license: + name: Apache 2.0 + url: 'http://www.apache.org/licenses/LICENSE-2.0.html' +security: + - OAuth2: [] + - BasicAuth: [] +paths: + /devices: + get: + tags: + - Device Management + summary: List all registered devices in the tenant. + operationId: listDevices + description: "This API provides the capability to list a paginated set of registered devices for the tenant.\n\n + Scope (Permission) required: ``internal_device_mgt_view``\n\n" + parameters: + - name: limit + in: query + description: Maximum number of records to return. + required: false + schema: + type: integer + minimum: 1 + default: 30 + - name: offset + in: query + description: Number of records to skip for pagination. + required: false + schema: + type: integer + minimum: 0 + default: 0 + - name: userId + in: query + description: Filter devices by the ID of the user who registered them. Returns devices of any status. Pagination applies as usual. + required: false + schema: + type: string + responses: + '200': + description: Successful Response + content: + application/json: + schema: + $ref: '#/components/schemas/DeviceListResponse' + '401': + description: Unauthorized + '403': + description: Forbidden + '500': + description: Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /devices/{device-id}: + get: + tags: + - Device Management + summary: Get a registered device by ID. + operationId: getDevice + description: "This API provides the capability to retrieve a registered device by its ID.\n\n + Scope (Permission) required: ``internal_device_mgt_view``\n\n" + parameters: + - name: device-id + in: path + description: UUID of the registered device + required: true + schema: + type: string + responses: + '200': + description: Successful Response + content: + application/json: + schema: + $ref: '#/components/schemas/DeviceResponse' + '401': + description: Unauthorized + '403': + description: Forbidden + '404': + description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + patch: + tags: + - Device Management + summary: Rename a registered device. + operationId: updateDeviceName + description: "This API provides the capability to update the display name of a registered device.\n\n + Scope (Permission) required: ``internal_device_mgt_update``\n\n" + parameters: + - name: device-id + in: path + description: UUID of the registered device + required: true + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/DevicePatchRequest' + responses: + '200': + description: Successful Response + content: + application/json: + schema: + $ref: '#/components/schemas/DeviceResponse' + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '401': + description: Unauthorized + '403': + description: Forbidden + '404': + description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + delete: + tags: + - Device Management + summary: Delete a registered device. + operationId: deleteDevice + description: "This API provides the capability to delete a registered device by its ID.\n\n + Scope (Permission) required: ``internal_device_mgt_delete``\n\n" + parameters: + - name: device-id + in: path + description: UUID of the registered device + required: true + schema: + type: string + responses: + '204': + description: Successfully Deleted + '401': + description: Unauthorized + '403': + description: Forbidden + '404': + description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +servers: + - url: 'https://localhost:9443/t/{tenant-domain}/api/server/v1' + variables: + tenant-domain: + default: carbon.super +components: + securitySchemes: + BasicAuth: + type: http + scheme: basic + OAuth2: + type: oauth2 + flows: + authorizationCode: + authorizationUrl: 'https://localhost:9443/oauth2/authorize' + tokenUrl: 'https://localhost:9443/oauth2/token' + scopes: + read: internal_device_mgt_view + write: internal_device_mgt_update + delete: internal_device_mgt_delete + schemas: + DeviceListResponse: + type: object + properties: + totalResults: + type: integer + description: Number of results that match the listing operation. + example: 42 + startIndex: + type: integer + description: Index of the first element of the page, which will be equal to offset + 1. + example: 1 + count: + type: integer + description: Number of elements in the returned page. + example: 10 + devices: + type: array + description: Page of registered devices. + items: + $ref: '#/components/schemas/DeviceResponse' + links: + type: array + description: Pagination links (next/previous). + items: + $ref: '#/components/schemas/DeviceListLink' + DeviceListLink: + type: object + properties: + href: + type: string + description: Relative URL to the linked page. + example: "/t/carbon.super/api/server/v1/devices?offset=10&limit=10" + rel: + type: string + description: Relation to the current page. + example: "next" + DeviceResponse: + type: object + properties: + id: + type: string + description: The device UUID. + example: "74070bae-df8c-42bf-8754-5173c237c936" + userId: + type: string + description: The user identifier who owns the device. + example: "kaviska" + deviceName: + type: string + description: The display name of the device. + example: "My iPhone" + deviceModel: + type: string + description: The hardware model of the device. + example: "iPhone 15 Pro" + status: + type: string + description: The current device status. + example: "ACTIVE" + registeredAt: + type: string + format: date-time + description: The timestamp when the device was registered. + example: "2026-04-27T10:00:00.000Z" + metadata: + type: string + description: Additional non-sensitive metadata associated with the device. + example: "{\"osVersion\":\"17.0\",\"deviceType\":\"mobile\",\"manufacturer\":\"Apple\"}" + DevicePatchRequest: + type: object + required: + - deviceName + properties: + deviceName: + type: string + minLength: 1 + maxLength: 255 + description: The new display name for the device. + example: "My Work Phone" + Error: + type: object + properties: + code: + type: string + example: DM-60001 + message: + type: string + example: Some Error Message. + description: + type: string + example: Some Error Description. + traceId: + type: string + example: "e0fbcfeb-3617-43c4-8dd0-7b7d38e13047" diff --git a/components/org.wso2.carbon.identity.api.server.device.mgt/pom.xml b/components/org.wso2.carbon.identity.api.server.device.mgt/pom.xml new file mode 100644 index 0000000000..366ffcd28a --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.device.mgt/pom.xml @@ -0,0 +1,36 @@ + + + + + + identity-api-server + org.wso2.carbon.identity.server.api + 1.6.36-SNAPSHOT + ../../pom.xml + + + 4.0.0 + org.wso2.carbon.identity.api.server.device.mgt + pom + + + org.wso2.carbon.identity.api.server.device.mgt.common + org.wso2.carbon.identity.api.server.device.mgt.v1 + + diff --git a/pom.xml b/pom.xml index 8a42a22e02..8fee623aef 100644 --- a/pom.xml +++ b/pom.xml @@ -965,6 +965,18 @@ ${project.version} provided + + org.wso2.carbon.identity.server.api + org.wso2.carbon.identity.api.server.device.mgt.common + ${project.version} + provided + + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.device.mgt + 7.11.110-SNAPSHOT + provided + org.wso2.carbon.identity.notification.push org.wso2.carbon.identity.notification.push.device.handler @@ -1216,6 +1228,7 @@ components/org.wso2.carbon.identity.api.server.vc.template.management components/org.wso2.carbon.identity.api.server.credential.management components/org.wso2.carbon.identity.api.server.moesif.publisher + components/org.wso2.carbon.identity.api.server.device.mgt From 8b8ebbce3c90f6a86a0cda6af334bb86d9595635 Mon Sep 17 00:00:00 2001 From: kaviska Date: Fri, 17 Jul 2026 09:03:52 +0530 Subject: [PATCH 2/3] Fix registeredAt serialization by using plain string timestamp --- .../server/device/mgt/v1/model/DeviceResponse.java | 13 ++++++------- .../mgt/v1/core/DeviceManagementApiService.java | 5 +---- .../src/main/resources/device-mgt.yaml | 3 +-- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/DeviceResponse.java b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/DeviceResponse.java index f975e58f3b..361e177e95 100644 --- a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/DeviceResponse.java +++ b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/gen/java/org/wso2/carbon/identity/api/server/device/mgt/v1/model/DeviceResponse.java @@ -22,7 +22,6 @@ import com.fasterxml.jackson.annotation.JsonCreator; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; -import java.time.OffsetDateTime; import javax.validation.constraints.*; @@ -38,7 +37,7 @@ public class DeviceResponse { private String deviceName; private String deviceModel; private String status; - private OffsetDateTime registeredAt; + private String registeredAt; private String metadata; /** @@ -137,21 +136,21 @@ public void setStatus(String status) { } /** - * The timestamp when the device was registered. + * The timestamp when the device was registered, in ISO-8601 format. **/ - public DeviceResponse registeredAt(OffsetDateTime registeredAt) { + public DeviceResponse registeredAt(String registeredAt) { this.registeredAt = registeredAt; return this; } - @ApiModelProperty(example = "2026-04-27T10:00Z", value = "The timestamp when the device was registered.") + @ApiModelProperty(example = "2026-04-27T10:00:00.000Z", value = "The timestamp when the device was registered, in ISO-8601 format.") @JsonProperty("registeredAt") @Valid - public OffsetDateTime getRegisteredAt() { + public String getRegisteredAt() { return registeredAt; } - public void setRegisteredAt(OffsetDateTime registeredAt) { + public void setRegisteredAt(String registeredAt) { this.registeredAt = registeredAt; } diff --git a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/v1/core/DeviceManagementApiService.java b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/v1/core/DeviceManagementApiService.java index ea4f3a5578..b3e1f54a5c 100644 --- a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/v1/core/DeviceManagementApiService.java +++ b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/java/org/wso2/carbon/identity/api/server/device/mgt/v1/core/DeviceManagementApiService.java @@ -36,8 +36,6 @@ import org.wso2.carbon.identity.device.mgt.api.model.Device; import org.wso2.carbon.identity.device.mgt.api.service.DeviceManagementService; -import java.time.OffsetDateTime; -import java.time.ZoneOffset; import java.util.List; import java.util.stream.Collectors; import javax.ws.rs.core.Response; @@ -197,8 +195,7 @@ private DeviceResponse toDeviceResponse(Device device) { response.setStatus(device.getStatus().name()); } if (device.getRegisteredAt() != null) { - response.setRegisteredAt( - OffsetDateTime.ofInstant(device.getRegisteredAt().toInstant(), ZoneOffset.UTC)); + response.setRegisteredAt(device.getRegisteredAt().toInstant().toString()); } response.setMetadata(device.getMetadata()); return response; diff --git a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/resources/device-mgt.yaml b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/resources/device-mgt.yaml index c0451ad326..e9a2491e4c 100644 --- a/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/resources/device-mgt.yaml +++ b/components/org.wso2.carbon.identity.api.server.device.mgt/org.wso2.carbon.identity.api.server.device.mgt.v1/src/main/resources/device-mgt.yaml @@ -264,8 +264,7 @@ components: example: "ACTIVE" registeredAt: type: string - format: date-time - description: The timestamp when the device was registered. + description: The timestamp when the device was registered, in ISO-8601 format. example: "2026-04-27T10:00:00.000Z" metadata: type: string From 24872996a7bba5197fa1dec2bda504b69fbfd45d Mon Sep 17 00:00:00 2001 From: kaviska Date: Fri, 17 Jul 2026 09:29:12 +0530 Subject: [PATCH 3/3] Use carbon.identity.framework.version for device mgt dependency --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8fee623aef..a29f1cb23c 100644 --- a/pom.xml +++ b/pom.xml @@ -974,7 +974,7 @@ org.wso2.carbon.identity.framework org.wso2.carbon.identity.device.mgt - 7.11.110-SNAPSHOT + ${carbon.identity.framework.version} provided