diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java index 3eefed7caa..ffe45ba3d3 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java @@ -585,20 +585,20 @@ public class GenericApplicationReleaseDAOImpl extends AbstractDAOImpl implements + "AR.CURRENT_STATE AS RELEASE_CURRENT_STATE, " + "AR.RATED_USERS AS RATED_USER_COUNT " + "FROM AP_APP_RELEASE AS AR " - + "WHERE AR.TENANT_ID = ? AND AR.PACKAGE_NAME IN ("; + + "WHERE AR.PACKAGE_NAME IN ("; - StringJoiner joiner = new StringJoiner(",", sql, ")"); + StringJoiner joiner = new StringJoiner(",", sql, ") AND AR.TENANT_ID = ? "); packages.stream().map(ignored -> "?").forEach(joiner::add); sql = joiner.toString(); try { Connection connection = this.getDBConnection(); try (PreparedStatement statement = connection.prepareStatement(sql)) { - statement.setInt(1, tenantId); - for (int y = 0; y < packages.size(); y++) { - // y +2 because tenantId parameter is 1 and the counter is starting at o for y - statement.setString(y+2, packages.get(y)); + int index = 1; + for (String packageName : packages) { + statement.setObject(index++, packageName); } + statement.setInt(index, tenantId); try (ResultSet resultSet = statement.executeQuery()) { List releaseDTOs = new ArrayList<>(); while (resultSet.next()) { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java index a4db52b032..b7f63a1f79 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java @@ -195,16 +195,21 @@ public class ApplicationManagerImpl implements ApplicationManager { ApplicationDTO applicationDTO = APIUtil.convertToAppDTO(publicAppWrapper); ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0); String appInstallerUrl = publicAppStorePath + applicationReleaseDTO.getPackageName(); - //todo check app package name exist or not, do it in validation method applicationReleaseDTO.setInstallerName(appInstallerUrl); applicationReleaseDTO.setUuid(UUID.randomUUID().toString()); applicationReleaseDTO.setAppHashValue(DigestUtils.md5Hex(appInstallerUrl)); - ConnectionManagerUtil.openDBConnection(); - List exitingRelease; try { - exitingRelease = applicationReleaseDAO.getReleaseByPackages(Arrays.asList(applicationReleaseDTO.getPackageName()) - , tenantId); + ConnectionManagerUtil.openDBConnection(); + List exitingPubAppReleases = applicationReleaseDAO + .getReleaseByPackages(Collections.singletonList(applicationReleaseDTO.getPackageName()), tenantId); + if (!exitingPubAppReleases.isEmpty()){ + String msg = "Public app release exists for package name " + applicationReleaseDTO.getPackageName() + + ". Hence you can't add new public app for package name " + + applicationReleaseDTO.getPackageName(); + log.error(msg); + throw new BadRequestException(msg); + } } catch (ApplicationManagementDAOException e) { String msg = "Error Occured when fetching release: " + publicAppWrapper.getName(); log.error(msg); @@ -213,45 +218,18 @@ public class ApplicationManagerImpl implements ApplicationManager { ConnectionManagerUtil.closeDBConnection(); } - if (exitingRelease != null && !exitingRelease.isEmpty()) { - applicationDTO.getApplicationReleaseDTOs().clear(); - applicationReleaseDTO.setUuid(exitingRelease.get(0).getUuid()); - applicationReleaseDTO.setCurrentState(exitingRelease.get(0).getCurrentState()); - - try { - applicationReleaseDTO = addImageArtifacts(applicationReleaseDTO, applicationArtifact, tenantId); - applicationDTO.getApplicationReleaseDTOs().add(applicationReleaseDTO); - ConnectionManagerUtil.beginDBTransaction(); - applicationReleaseDAO.updateRelease(applicationReleaseDTO, tenantId); - ConnectionManagerUtil.commitDBTransaction(); - return APIUtil.appDtoToAppResponse(applicationDTO); - } catch (ApplicationManagementDAOException e) { - ConnectionManagerUtil.rollbackDBTransaction(); - String msg = "Error occurred when updating public app: " + publicAppWrapper.getName(); - log.error(msg, e); - throw new ApplicationManagementException(msg, e); - } catch (ResourceManagementException e) { - String msg = "Error occurred when adding artifacts of release: " + publicAppWrapper.getName(); - log.error(msg, e); - throw new ApplicationManagementException(msg, e); - } finally { - ConnectionManagerUtil.closeDBConnection(); - } - } else { + try { //uploading application artifacts - try { - applicationReleaseDTO = addImageArtifacts(applicationReleaseDTO, applicationArtifact, tenantId); - applicationDTO.getApplicationReleaseDTOs().clear(); - applicationDTO.getApplicationReleaseDTOs().add(applicationReleaseDTO); - } catch (ResourceManagementException e) { - String msg = "Error Occured when uploading artifacts of the public app: " + publicAppWrapper.getName(); - log.error(msg, e); - throw new ApplicationManagementException(msg, e); - } - //insert application data into database - return addAppDataIntoDB(applicationDTO, tenantId); + applicationReleaseDTO = addImageArtifacts(applicationReleaseDTO, applicationArtifact, tenantId); + applicationDTO.getApplicationReleaseDTOs().clear(); + applicationDTO.getApplicationReleaseDTOs().add(applicationReleaseDTO); + } catch (ResourceManagementException e) { + String msg = "Error Occured when uploading artifacts of the public app: " + publicAppWrapper.getName(); + log.error(msg, e); + throw new ApplicationManagementException(msg, e); } - + //insert application data into database + return addAppDataIntoDB(applicationDTO, tenantId); } @Override @@ -316,6 +294,13 @@ public class ApplicationManagerImpl implements ApplicationManager { } } + /** + * Delete Application release artifacts + * + * @param directoryPaths Directory paths + * @param tenantId Tenant Id + * @throws ApplicationManagementException if error occurred while deleting application release artifacts. + */ private void deleteApplicationArtifacts(List directoryPaths, int tenantId) throws ApplicationManagementException { ApplicationStorageManager applicationStorageManager = DAOUtil.getApplicationStorageManager(); try { @@ -328,6 +313,17 @@ public class ApplicationManagerImpl implements ApplicationManager { } } + /** + * To add Application release artifacts + * + * @param deviceType Device Type + * @param applicationReleaseDTO Application Release + * @param applicationArtifact Application release artifacts + * @param isNewRelease Is new release or Not + * @return {@link ApplicationReleaseDTO} + * @throws ResourceManagementException if error occurred while handling application release artifacts. + * @throws ApplicationManagementException if error occurred while handling application release data. + */ private ApplicationReleaseDTO addApplicationReleaseArtifacts(String deviceType, ApplicationReleaseDTO applicationReleaseDTO, ApplicationArtifact applicationArtifact, boolean isNewRelease) throws ResourceManagementException, ApplicationManagementException { @@ -402,6 +398,16 @@ public class ApplicationManagerImpl implements ApplicationManager { return applicationReleaseDTO; } + /** + * This method could be used to update enterprise application release artifacts. + * + * @param deviceType Device Type + * @param applicationReleaseDTO Application Release + * @param applicationArtifact Application release artifacts + * @return {@link ApplicationReleaseDTO} + * @throws ResourceManagementException if error occurred while handling application release artifacts. + * @throws ApplicationManagementException if error occurred while handling application release data. + */ private ApplicationReleaseDTO updateEntAppReleaseArtifact(String deviceType, ApplicationReleaseDTO applicationReleaseDTO, ApplicationArtifact applicationArtifact) throws ResourceManagementException, ApplicationManagementException { @@ -489,6 +495,15 @@ public class ApplicationManagerImpl implements ApplicationManager { return applicationReleaseDTO; } + /** + * Add image artifacts into file system + * + * @param applicationReleaseDTO Application Release + * @param applicationArtifact Image artifacts + * @param tenantId Tenant Id + * @return {@link ApplicationReleaseDTO} + * @throws ResourceManagementException if error occurred while uploading image artifacts into file system. + */ private ApplicationReleaseDTO addImageArtifacts(ApplicationReleaseDTO applicationReleaseDTO, ApplicationArtifact applicationArtifact, int tenantId) throws ResourceManagementException { ApplicationStorageManager applicationStorageManager = DAOUtil.getApplicationStorageManager(); @@ -518,6 +533,14 @@ public class ApplicationManagerImpl implements ApplicationManager { return applicationReleaseDTO; } + /** + * Update Image artifacts of Application RApplication Release + * + * @param applicationArtifact Application release Artifacts + * @param tenantId Tenant Id + * @return {@link ApplicationReleaseDTO} + * @throws ResourceManagementException if error occurred while uploading application release artifacts into the file system. + */ private ApplicationReleaseDTO updateImageArtifacts(ApplicationReleaseDTO applicationReleaseDTO, ApplicationArtifact applicationArtifact, int tenantId) throws ResourceManagementException{ ApplicationStorageManager applicationStorageManager = DAOUtil.getApplicationStorageManager(); @@ -674,9 +697,19 @@ public class ApplicationManagerImpl implements ApplicationManager { } } + /** + * Check whether at least one filtering role is in app unrestricted roles. + * + * @param appUnrestrictedRoles Application unrestricted roles + * @param filteringUnrestrictedRoles Filtering roles + * @param userName Username + * @return True if one filtering unrestricted role is associated with application unrestricted roles. + * @throws BadRequestException if user doesn't have assigned at least one filtering role + * @throws UserStoreException if error occurred when checking whether user has assigned at least one filtering role. + */ private boolean hasAppUnrestrictedRole(List appUnrestrictedRoles, List filteringUnrestrictedRoles, String userName) throws BadRequestException, UserStoreException { - if (!haveAllUserRoles(filteringUnrestrictedRoles, userName)) { + if (!hasUserRole(filteringUnrestrictedRoles, userName)) { String msg = "At least one filtering role is not assigned for the user: " + userName + ". Hence user " + userName + " Can't filter applications by giving these unrestricted role list"; @@ -850,7 +883,7 @@ public class ApplicationManagerImpl implements ApplicationManager { throw new BadRequestException(msg); } DeviceType deviceType = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); - if (!isValidOsVersions(entAppReleaseWrapper.getSupportedOsVersions(), deviceType.getName())) { + if (isInvalidOsVersionRange(entAppReleaseWrapper.getSupportedOsVersions(), deviceType.getName())) { String msg = "You are trying to add application release which has invalid or unsupported OS versions in " + "the supportedOsVersions section. Hence, please re-evaluate the request payload."; log.error(msg); @@ -897,6 +930,13 @@ public class ApplicationManagerImpl implements ApplicationManager { } } + /** + * Get Application and all application releases associated to the application that has given application Id + * + * @param applicationId Application Id + * @return {@link ApplicationDTO} + * @throws ApplicationManagementException if error occurred application data from the databse. + */ private ApplicationDTO getApplication(int applicationId) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); try { @@ -909,8 +949,8 @@ public class ApplicationManagerImpl implements ApplicationManager { } return applicationDTO; } catch (DBConnectionException e) { - String msg = "Error occurred while obtaining the database connection for getting application for the " - + "application ID: " + applicationId; + String msg = "Error occurred while obtaining the database connection for getting application for the app ID" + + " " + applicationId; log.error(msg, e); throw new ApplicationManagementException(msg, e); } catch (ApplicationManagementDAOException e) { @@ -922,6 +962,17 @@ public class ApplicationManagerImpl implements ApplicationManager { } } + /** + * Upload enterprise application release artifact into file system. + * + * @param releaseDTO Apllication Release + * @param applicationArtifact Application Release artifacts + * @param deviceTypeName Device Type name + * @param tenantId Tenant Id + * @param isNewRelease New Release or Not + * @return {@link ApplicationReleaseDTO} + * @throws ApplicationManagementException if error occurred while uploading artifacts into file system. + */ private ApplicationReleaseDTO uploadEntAppReleaseArtifacts(ApplicationReleaseDTO releaseDTO, ApplicationArtifact applicationArtifact, String deviceTypeName, int tenantId, boolean isNewRelease) throws ApplicationManagementException { @@ -936,7 +987,16 @@ public class ApplicationManagerImpl implements ApplicationManager { } } - private boolean isValidOsVersions(String osRange, String deviceTypeName) + /** + * Check whether given OS range is valid or invalid + * + * @param osRange OS range + * @param deviceTypeName Device Type + * @return true if invalid OS range, Otherwise returns false + * @throws ApplicationManagementException if error occurred while getting device type version for lower OS version + * and higher OS version + */ + private boolean isInvalidOsVersionRange(String osRange, String deviceTypeName) throws ApplicationManagementException { String lowestSupportingOsVersion; String highestSupportingOsVersion = null; @@ -949,9 +1009,9 @@ public class ApplicationManagerImpl implements ApplicationManager { try { DeviceManagementProviderService deviceManagementProviderService = DAOUtil.getDeviceManagementService(); return deviceManagementProviderService.getDeviceTypeVersion(deviceTypeName, lowestSupportingOsVersion) - != null && (highestSupportingOsVersion == null - || deviceManagementProviderService.getDeviceTypeVersion(deviceTypeName, highestSupportingOsVersion) - != null); + == null || (highestSupportingOsVersion != null + && deviceManagementProviderService.getDeviceTypeVersion(deviceTypeName, highestSupportingOsVersion) + == null); } catch (DeviceManagementException e) { String msg = "Error occurred while getting supported device type versions for device type : " + deviceTypeName; @@ -1152,9 +1212,16 @@ public class ApplicationManagerImpl implements ApplicationManager { } } + /** + * Check whether at least one role is assigned to the given user. + * + * @param unrestrictedRoleList unrestricted role list + * @param userName Username + * @return true at least one unrestricted role has assigned to given user, otherwise returns false. + * @throws UserStoreException If it is unable to load {@link UserRealm} from {@link CarbonContext} + */ private boolean hasUserRole(Collection unrestrictedRoleList, String userName) throws UserStoreException { - String[] roleList; - roleList = getRolesOfUser(userName); + String[] roleList = getRolesOfUser(userName); for (String unrestrictedRole : unrestrictedRoleList) { for (String role : roleList) { if (unrestrictedRole.equals(role)) { @@ -1165,30 +1232,18 @@ public class ApplicationManagerImpl implements ApplicationManager { return false; } - private boolean haveAllUserRoles(Collection unrestrictedRoleList, String userName) - throws UserStoreException { - String[] roleList; - roleList = getRolesOfUser(userName); - for (String unrestrictedRole : unrestrictedRoleList) { - for (String role : roleList) { - if (!unrestrictedRole.equals(role)) { - return false; - } - } - } - return true; - } - + /** + * Check whether valid unrestricted role list or not + * + * @return true or false + * @throws UserStoreException If it is unable to load {@link UserRealm} from {@link CarbonContext} + */ private boolean isValidRestrictedRole(Collection unrestrictedRoleList) throws UserStoreException { - List roleList = new ArrayList<>(Arrays.asList(getRoleNames())); - return roleList.containsAll(unrestrictedRoleList); - } - - private String[] getRoleNames() throws UserStoreException { //todo check role by role UserRealm userRealm = CarbonContext.getThreadLocalCarbonContext().getUserRealm(); if (userRealm != null) { - return userRealm.getUserStoreManager().getRoleNames(); + List roleList = new ArrayList<>(Arrays.asList(userRealm.getUserStoreManager().getRoleNames())); + return roleList.containsAll(unrestrictedRoleList); } else { String msg = "User realm is not initiated."; log.error(msg); @@ -1196,6 +1251,13 @@ public class ApplicationManagerImpl implements ApplicationManager { } } + /** + * Get assigned role list of the given user. + * + * @param userName Username + * @return List of roles + * @throws UserStoreException If it is unable to load {@link UserRealm} from {@link CarbonContext} + */ private String[] getRolesOfUser(String userName) throws UserStoreException { UserRealm userRealm = CarbonContext.getThreadLocalCarbonContext().getUserRealm(); String[] roleList; @@ -2119,6 +2181,7 @@ public class ApplicationManagerImpl implements ApplicationManager { } } + @Override public List addApplicationTags(int appId, List tags) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); try { @@ -2171,6 +2234,7 @@ public class ApplicationManagerImpl implements ApplicationManager { } } + @Override public List addCategories(List categories) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); try { @@ -2291,7 +2355,12 @@ public class ApplicationManagerImpl implements ApplicationManager { return lifecycleStateManager.getInstallableState(); } - + /** + * This method can be used to validate {@link Filter} object. + * + * @param filter {@link Filter} + * @throws BadRequestException if filter object contains incompatible data. + */ private void validateFilter(Filter filter) throws BadRequestException { if (filter == null) { String msg = "Filter validation is failed, Filter shouldn't be null, hence please verify the request payload"; @@ -2340,9 +2409,16 @@ public class ApplicationManagerImpl implements ApplicationManager { log.error(msg); throw new BadRequestException(msg); } - } + /** + * This method can be used to get difference of two lists. + * + * @param list1 List of objects + * @param list2 List of object + * @param Object type + * @return return list of values which are not in the list2 but in the list1 + */ private List getDifference(List list1, Collection list2) { List list = new ArrayList<>(); for (T t : list1) { @@ -2353,7 +2429,7 @@ public class ApplicationManagerImpl implements ApplicationManager { return list; } - /*** + /** * By invoking the method, it returns Lifecycle State Instance. * @param currentState Current state of the lifecycle * @param previousState Previouse state of the Lifecycle @@ -2726,7 +2802,7 @@ public class ApplicationManagerImpl implements ApplicationManager { .equals(appType)) { DeviceType deviceTypeObj = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); String supportedOSVersions = applicationReleaseDTO.getSupportedOsVersions(); - if (!StringUtils.isEmpty(supportedOSVersions) && !isValidOsVersions(supportedOSVersions, + if (!StringUtils.isEmpty(supportedOSVersions) && isInvalidOsVersionRange(supportedOSVersions, deviceTypeObj.getName())) { String msg = "You are trying to update application release which has invalid or unsupported OS " + "versions in the supportedOsVersions section. Hence, please re-evaluate the request payload."; @@ -2736,7 +2812,6 @@ public class ApplicationManagerImpl implements ApplicationManager { } } - @Override public void validateAppCreatingRequest(T param) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); @@ -2988,7 +3063,7 @@ public class ApplicationManagerImpl implements ApplicationManager { log.error(msg); throw new BadRequestException(msg); } - if (!isValidOsVersions(entAppReleaseWrapper.get().getSupportedOsVersions(), deviceType)) { + if (isInvalidOsVersionRange(entAppReleaseWrapper.get().getSupportedOsVersions(), deviceType)) { String msg = "You are trying to create application which has an application release contains invalid or " + "unsupported OS versions in the supportedOsVersions section. Hence, please re-evaluate the " + "request payload."; @@ -3031,7 +3106,7 @@ public class ApplicationManagerImpl implements ApplicationManager { log.error(msg); throw new BadRequestException(msg); } - if (!isValidOsVersions(publicAppReleaseWrapper.getSupportedOsVersions(), deviceType)) { + if (isInvalidOsVersionRange(publicAppReleaseWrapper.getSupportedOsVersions(), deviceType)) { String msg = "You are trying to create application which has an application release contains invalid or " + "unsupported OS versions in the supportedOsVersions section. Hence, please re-evaluate the " + "request payload."; diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/ApplicationManagementPublisherAPIImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/ApplicationManagementPublisherAPIImpl.java index 499b59815b..5e0e765239 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/ApplicationManagementPublisherAPIImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/ApplicationManagementPublisherAPIImpl.java @@ -198,12 +198,16 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem log.error(msg); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } + } catch (BadRequestException e) { + String msg = "Found incompatible payload with ent. app creating request."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } catch (ApplicationManagementException e) { String msg = "Error occurred while creating the ent. application"; log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } catch (RequestValidatingException e) { - String msg = "Error occurred while handling the ent. application creating request"; + String msg = "Couldn't find the required artifacts to create new ent. application with the request"; log.error(msg, e); return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } @@ -237,12 +241,16 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem log.error(msg); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } + } catch (BadRequestException e) { + String msg = "Found incompatible payload with web app creating request."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } catch (ApplicationManagementException e) { String msg = "Error occurred while creating the web application"; log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } catch (RequestValidatingException e) { - String msg = "Error occurred while handling the web app creating request"; + String msg = "Couldn't find the required artifacts to create new web application with the request"; log.error(msg, e); return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } @@ -276,12 +284,16 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem log.error(msg); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } + } catch (BadRequestException e) { + String msg = "Found incompatible payload with pub app creating request."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } catch (ApplicationManagementException e) { String msg = "Error occurred while creating the public app."; log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } catch (RequestValidatingException e) { - String msg = "Error occurred while handling the public app creating request"; + String msg = "Couldn't find the required artifacts to create new public application with the request"; log.error(msg, e); return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } @@ -317,12 +329,16 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem log.error(msg); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } + } catch (BadRequestException e) { + String msg = "Found incompatible payload with pub custom creating request."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } catch (ApplicationManagementException e) { String msg = "Error occurred while creating the application"; log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } catch (RequestValidatingException e) { - String msg = "Error occurred while handling the application creating request"; + String msg = "Couldn't find the required artifacts to create new custom application with the request"; log.error(msg, e); return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } @@ -908,6 +924,7 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem } /*** + * This method can be used to construct {@link ApplicationArtifact} * * @param binaryFile binary file of the application release * @param iconFile icon file of the application release diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/package.json b/components/device-mgt/io.entgra.device.mgt.ui/react-app/package.json index 3f4470ef19..2471a872d9 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/package.json +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/package.json @@ -17,12 +17,11 @@ "moment": "latest", "prop-types": "latest", "rc-viewer": "0.0.9", - "react-advanced-datetimerange-picker": "^1.0.8", + "react-bootstrap": "^1.0.0-beta.12", "react-highlight-words": "^0.16.0", "react-image-viewer-zoom": "^1.0.36", "react-infinite-scroller": "^1.2.4", "react-leaflet": "^2.4.0", - "react-bootstrap": "^1.0.0-beta.12", "react-moment": "^0.9.2", "react-router": "^5.0.1", "react-router-config": "^5.0.1", @@ -31,6 +30,7 @@ "react-star-ratings": "^2.3.0", "react-twemoji": "^0.2.3", "react-virtualized": "^9.21.1", + "react-websocket": "^2.1.0", "reqwest": "^2.0.5", "storm-react-diagrams": "^5.2.1" }, diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/conf/config.json b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/conf/config.json index aa72ba06e4..916421e377 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/conf/config.json +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/conf/config.json @@ -1,6 +1,6 @@ { "theme": { - "logo" : "https://localhost:9443/entgra/public/images/logo.svg", + "logo" : "https://entgra.io/assets/images/svg/logo.svg", "primaryColor": "rgb(24, 144, 255)" }, "serverConfig": { diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/logo.svg b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/logo.svg index 05eb79a811..7986a8d1b4 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/logo.svg +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/logo.svg @@ -1 +1,798 @@ -logo \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.js index 68f8823e1a..5f8f429e8e 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.js @@ -67,11 +67,8 @@ class App extends React.Component { axios.get( window.location.origin + "/entgra/public/conf/config.json", ).then(res => { - console.log(res); - this.setState({ - loading: false, - config: res.data - }) + const config = res.data; + this.checkUserLoggedIn(config); }).catch((error) => { this.setState({ loading: false, @@ -80,6 +77,44 @@ class App extends React.Component { }); } + checkUserLoggedIn = (config) => { + axios.post( + window.location.origin + "/entgra-ui-request-handler/user", + "platform=entgra" + ).then(res => { + config.user = res.data.data; + const pageURL = window.location.pathname; + const lastURLSegment = pageURL.substr(pageURL.lastIndexOf('/') + 1); + if (lastURLSegment === "login") { + window.location.href = window.location.origin + `/entgra/`; + } else { + this.setState({ + loading: false, + config: config + }); + } + }).catch((error) => { + if (error.hasOwnProperty("response") && error.response.status === 401) { + const redirectUrl = encodeURI(window.location.href); + const pageURL = window.location.pathname; + const lastURLSegment = pageURL.substr(pageURL.lastIndexOf('/') + 1); + if (lastURLSegment !== "login") { + window.location.href = window.location.origin + `/entgra/login?redirect=${redirectUrl}`; + } else { + this.setState({ + loading: false, + config: config + }) + } + } else { + this.setState({ + loading: false, + error: true + }) + } + }); + }; + render() { const {loading, error} = this.state; diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/DeviceTypes/DeviceTypesTable.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/DeviceTypes/DeviceTypesTable.js new file mode 100644 index 0000000000..42af8271b7 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/DeviceTypes/DeviceTypesTable.js @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from "react"; +import axios from "axios"; +import {message, notification, Typography, Icon, Card, Col, Row} from "antd"; +import TimeAgo from 'javascript-time-ago' + +// Load locale-specific relative date/time formatting rules. +import en from 'javascript-time-ago/locale/en' +import {withConfigContext} from "../../context/ConfigContext"; + +const {Text} = Typography; + +let config = null; +let apiUrl; + +class DeviceTypesTable extends React.Component { + constructor(props) { + super(props); + config = this.props.context; + TimeAgo.addLocale(en); + this.state = { + data: [], + pagination: {}, + loading: false, + selectedRows: [] + }; + } + + componentDidMount() { + this.fetchUsers(); + } + + //fetch data from api + fetchUsers = (params = {}) => { + const config = this.props.context; + this.setState({loading: true}); + + // get current page + const currentPage = (params.hasOwnProperty("page")) ? params.page : 1; + + const extraParams = { + offset: 10 * (currentPage - 1), //calculate the offset + limit: 10, + }; + + const encodedExtraParams = Object.keys(extraParams) + .map(key => key + '=' + extraParams[key]).join('&'); + + apiUrl = window.location.origin + config.serverConfig.invoker.uri + + config.serverConfig.invoker.deviceMgt + + "/device-types"; + + //send request to the invokerss + axios.get(apiUrl).then(res => { + if (res.status === 200) { + const pagination = {...this.state.pagination}; + this.setState({ + loading: false, + data: JSON.parse(res.data.data), + pagination, + }); + } + + }).catch((error) => { + if (error.hasOwnProperty("response") && error.response.status === 401) { + //todo display a popop with error + message.error('You are not logged in'); + window.location.href = window.location.origin + '/entgra/login'; + } else { + notification["error"]({ + message: "There was a problem", + duration: 0, + description:"Error occurred while trying to load device types.", + }); + } + + this.setState({loading: false}); + }); + }; + + handleTableChange = (pagination, filters, sorter) => { + const pager = {...this.state.pagination}; + pager.current = pagination.current; + this.setState({ + pagination: pager, + }); + this.fetch({ + results: pagination.pageSize, + page: pagination.current, + sortField: sorter.field, + sortOrder: sorter.order, + ...filters, + }); + }; + + render() { + + const {data, pagination, loading, selectedRows} = this.state; + const { Meta } = Card; + const itemCard = data.map((data) => + + , + ,]} + > + } + title={data.name} + /> + + + + ); + return ( +
+ + {itemCard} + +
+ ); + } +} + +export default withConfigContext(DeviceTypesTable); \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/DevicesTable.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/DevicesTable.js index 62cb0c9f14..38e5444aeb 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/DevicesTable.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/DevicesTable.js @@ -18,7 +18,7 @@ import React from "react"; import axios from "axios"; -import {Tag, message, notification, Table, Typography, Tooltip, Icon, Divider, Button, Modal, Select} from "antd"; +import {Tag, message, notification, Table, Typography, Tooltip, Icon, Modal, Select} from "antd"; import TimeAgo from 'javascript-time-ago' // Load locale-specific relative date/time formatting rules. @@ -133,18 +133,11 @@ class DeviceTable extends React.Component { selectedRows: [], deviceGroups: [], groupModalVisible: false, - selectedGroupId: [] + selectedGroupId: [], + selectedRowKeys:[] }; } - rowSelection = { - onChange: (selectedRowKeys, selectedRows) => { - this.setState({ - selectedRows: selectedRows - }); - } - }; - componentDidMount() { this.fetch(); } @@ -176,7 +169,7 @@ class DeviceTable extends React.Component { this.setState({ loading: false, data: res.data.data.devices, - pagination, + pagination }); } @@ -249,11 +242,14 @@ class DeviceTable extends React.Component { ).then(res => { if (res.status === 200) { this.fetch(); + this.setState({ + selectedRowKeys:[] + }) notification["success"]({ message: "Done", duration: 4, description: - "Successfully disenrolled the device.", + "Successfully dis-enrolled the device.", }); } }).catch((error) => { @@ -266,7 +262,7 @@ class DeviceTable extends React.Component { message: "There was a problem", duration: 0, description: - "Error occurred while trying to disenroll devices.", + "Error occurred while trying to dis-enroll devices.", }); } @@ -409,11 +405,30 @@ class DeviceTable extends React.Component { }); }; - render() { - const {data, pagination, loading, selectedRows} = this.state; + onSelectChange = (selectedRowKeys, selectedRows) => { + this.setState({ + selectedRowKeys, + selectedRows: selectedRows + }); + }; + render() { + const {data, pagination, loading, selectedRows, selectedRowKeys} = this.state; const isSelectedSingle = this.state.selectedRows.length == 1; + let selectedText; + if(isSelectedSingle){ + selectedText = "You have selected 1 device" + }else{ + selectedText = "You have selected " + this.state.selectedRows.length + " devices" + } + + const rowSelection = { + selectedRowKeys, + selectedRows, + onChange: this.onSelectChange, + }; + let item = this.state.deviceGroups.map((data) => @@ -453,10 +467,11 @@ class DeviceTable extends React.Component { onOk={this.handleOk} onCancel={this.handleCancel} > +

{selectedText}

enrolmentInfo.owner + // todo add filtering options + }, + { + title: 'Description', + dataIndex: 'description', + key: 'description', + // render: enrolmentInfo => enrolmentInfo.ownership + // todo add filtering options + } +]; + +const getTimeAgo = (time) => { + const timeAgo = new TimeAgo('en-US'); + return timeAgo.format(time); +}; + +class GroupsTable extends React.Component { + constructor(props) { + super(props); + config = this.props.context; + TimeAgo.addLocale(en); + this.state = { + data: [], + pagination: {}, + loading: false, + selectedRows: [] + }; + } + + rowSelection = { + onChange: (selectedRowKeys, selectedRows) => { + this.setState({ + selectedRows: selectedRows + }) + } + }; + + componentDidMount() { + this.fetchGroups(); + } + + //fetch data from api + fetchGroups = (params = {}) => { + const config = this.props.context; + this.setState({loading: true}); + + // get current page + const currentPage = (params.hasOwnProperty("page")) ? params.page : 1; + + const extraParams = { + offset: 10 * (currentPage - 1), //calculate the offset + limit: 10, + }; + + const encodedExtraParams = Object.keys(extraParams) + .map(key => key + '=' + extraParams[key]).join('&'); + + apiUrl = window.location.origin + config.serverConfig.invoker.uri + + config.serverConfig.invoker.deviceMgt + + "/admin/groups?" + encodedExtraParams; + + //send request to the invokerss + axios.get(apiUrl).then(res => { + if (res.status === 200) { + const pagination = {...this.state.pagination}; + this.setState({ + loading: false, + data: res.data.data.deviceGroups, + pagination, + }); + } + + }).catch((error) => { + if (error.hasOwnProperty("response") && error.response.status === 401) { + //todo display a popop with error + message.error('You are not logged in'); + window.location.href = window.location.origin + '/entgra/login'; + } else { + notification["error"]({ + message: "There was a problem", + duration: 0, + description:"Error occurred while trying to load device groups.", + }); + } + + this.setState({loading: false}); + }); + }; + + handleTableChange = (pagination, filters, sorter) => { + const pager = {...this.state.pagination}; + pager.current = pagination.current; + this.setState({ + pagination: pager, + }); + this.fetch({ + results: pagination.pageSize, + page: pagination.current, + sortField: sorter.field, + sortOrder: sorter.order, + ...filters, + }); + }; + + render() { + + const {data, pagination, loading, selectedRows} = this.state; + return ( +
+ (record.id)} + dataSource={data} + pagination={{ + ...pagination, + size: "small", + // position: "top", + showTotal: (total, range) => `showing ${range[0]}-${range[1]} of ${total} groups` + // showQuickJumper: true + }} + loading={loading} + onChange={this.handleTableChange} + rowSelection={this.rowSelection} + /> + + ); + } +} + +export default withConfigContext(GroupsTable); \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Policies/PoliciesTable.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Policies/PoliciesTable.js new file mode 100644 index 0000000000..5a1fbb3692 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Policies/PoliciesTable.js @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from "react"; +import axios from "axios"; +import {message, notification, Table, Typography} from "antd"; +import TimeAgo from 'javascript-time-ago' + +// Load locale-specific relative date/time formatting rules. +import en from 'javascript-time-ago/locale/en' +import {withConfigContext} from "../../context/ConfigContext"; + +const {Text} = Typography; + +let config = null; +let apiUrl; + +const columns = [ + { + title: 'Policy Name', + dataIndex: 'policyName', + width: 100, + }, + { + title: 'Description', + dataIndex: 'description', + key: 'description', + // render: enrolmentInfo => enrolmentInfo.owner + // todo add filtering options + }, + { + title: 'Compilance', + dataIndex: 'compliance', + key: 'compliance', + // render: enrolmentInfo => enrolmentInfo.ownership + // todo add filtering options + }, + { + title: 'Policy Type', + dataIndex: 'policyType', + key: 'policyType', + // render: enrolmentInfo => enrolmentInfo.ownership + // todo add filtering options + } +]; + +const getTimeAgo = (time) => { + const timeAgo = new TimeAgo('en-US'); + return timeAgo.format(time); +}; + +class PoliciesTable extends React.Component { + constructor(props) { + super(props); + config = this.props.context; + TimeAgo.addLocale(en); + this.state = { + data: [], + pagination: {}, + loading: false, + selectedRows: [] + }; + } + + rowSelection = { + onChange: (selectedRowKeys, selectedRows) => { + this.setState({ + selectedRows: selectedRows + }) + } + }; + + componentDidMount() { + this.fetchGroups(); + } + + //fetch data from api + fetchGroups = (params = {}) => { + const config = this.props.context; + this.setState({loading: true}); + + // get current page + const currentPage = (params.hasOwnProperty("page")) ? params.page : 1; + + const extraParams = { + offset: 10 * (currentPage - 1), //calculate the offset + limit: 10, + }; + + const encodedExtraParams = Object.keys(extraParams) + .map(key => key + '=' + extraParams[key]).join('&'); + + apiUrl = window.location.origin + config.serverConfig.invoker.uri + + config.serverConfig.invoker.deviceMgt + + "/policies?" + encodedExtraParams; + + //send request to the invokerss + axios.get(apiUrl).then(res => { + if (res.status === 200) { + const pagination = {...this.state.pagination}; + this.setState({ + loading: false, + data: res.data.data.policies, + pagination, + }); + } + + }).catch((error) => { + if (error.hasOwnProperty("response") && error.response.status === 401) { + //todo display a popop with error + message.error('You are not logged in'); + window.location.href = window.location.origin + '/entgra/login'; + } else { + notification["error"]({ + message: "There was a problem", + duration: 0, + description:"Error occurred while trying to load policies.", + }); + } + + this.setState({loading: false}); + }); + }; + + handleTableChange = (pagination, filters, sorter) => { + const pager = {...this.state.pagination}; + pager.current = pagination.current; + this.setState({ + pagination: pager, + }); + this.fetch({ + results: pagination.pageSize, + page: pagination.current, + sortField: sorter.field, + sortOrder: sorter.order, + ...filters, + }); + }; + + render() { + + const {data, pagination, loading, selectedRows} = this.state; + return ( +
+
(record.id)} + dataSource={data} + pagination={{ + ...pagination, + size: "small", + // position: "top", + showTotal: (total, range) => `showing ${range[0]}-${range[1]} of ${total} groups` + // showQuickJumper: true + }} + loading={loading} + onChange={this.handleTableChange} + rowSelection={this.rowSelection} + /> + + ); + } +} + +export default withConfigContext(PoliciesTable); \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Roles/RolesTable.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Roles/RolesTable.js new file mode 100644 index 0000000000..1080cddddb --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Roles/RolesTable.js @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from "react"; +import axios from "axios"; +import {Tag, message, notification, Table, Typography, Tooltip, Icon, Divider, Card, Col, Row, Select} from "antd"; +import TimeAgo from 'javascript-time-ago' + +// Load locale-specific relative date/time formatting rules. +import en from 'javascript-time-ago/locale/en' +import {withConfigContext} from "../../context/ConfigContext"; + +const {Text} = Typography; + +let config = null; +let apiUrl; + +const columns = [ + { + title: 'User Name', + dataIndex: 'username', + width: 100, + } +]; + +const getTimeAgo = (time) => { + const timeAgo = new TimeAgo('en-US'); + return timeAgo.format(time); +}; + +class RolesTable extends React.Component { + constructor(props) { + super(props); + config = this.props.context; + TimeAgo.addLocale(en); + this.state = { + data: [], + pagination: {}, + loading: false, + selectedRows: [] + }; + } + + componentDidMount() { + this.fetchUsers(); + } + + //fetch data from api + fetchUsers = (params = {}) => { + const config = this.props.context; + this.setState({loading: true}); + + // get current page + const currentPage = (params.hasOwnProperty("page")) ? params.page : 1; + + const extraParams = { + offset: 10 * (currentPage - 1), //calculate the offset + limit: 10, + }; + + const encodedExtraParams = Object.keys(extraParams) + .map(key => key + '=' + extraParams[key]).join('&'); + + apiUrl = window.location.origin + config.serverConfig.invoker.uri + + config.serverConfig.invoker.deviceMgt + + "/roles"; + + //send request to the invokerss + axios.get(apiUrl).then(res => { + if (res.status === 200) { + const pagination = {...this.state.pagination}; + this.setState({ + loading: false, + data: res.data.data.roles, + pagination, + }); + } + + }).catch((error) => { + if (error.hasOwnProperty("response") && error.response.status === 401) { + //todo display a popop with error + message.error('You are not logged in'); + window.location.href = window.location.origin + '/entgra/login'; + } else { + notification["error"]({ + message: "There was a problem", + duration: 0, + description:"Error occurred while trying to load users.", + }); + } + + this.setState({loading: false}); + }); + }; + + handleTableChange = (pagination, filters, sorter) => { + const pager = {...this.state.pagination}; + pager.current = pagination.current; + this.setState({ + pagination: pager, + }); + this.fetch({ + results: pagination.pageSize, + page: pagination.current, + sortField: sorter.field, + sortOrder: sorter.order, + ...filters, + }); + }; + + render() { + + const {data, pagination, loading, selectedRows} = this.state; + const { Meta } = Card; + const itemCard = data.map((data) => + + , + ,]} + > + } + title={data} + /> + + + ); + return ( +
+ + {itemCard} + +
+ ); + } +} + +export default withConfigContext(RolesTable); \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersDevices.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersDevices.js new file mode 100644 index 0000000000..75529becc1 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersDevices.js @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from "react"; +import axios from "axios"; +import {Tag, message, notification, Table, Typography, Tooltip, Icon, Divider} from "antd"; +import TimeAgo from 'javascript-time-ago' + +// Load locale-specific relative date/time formatting rules. +import en from 'javascript-time-ago/locale/en' +import {withConfigContext} from "../../context/ConfigContext"; + +const {Text} = Typography; + +let config = null; +let apiUrl; + +const columns = [ + { + title: 'Device', + dataIndex: 'name', + width: 100, + }, + { + title: 'Type', + dataIndex: 'type', + key: 'type', + render: type => { + const defaultPlatformIcons = config.defaultPlatformIcons; + let icon = defaultPlatformIcons.default.icon; + let color = defaultPlatformIcons.default.color; + let theme = defaultPlatformIcons.default.theme; + + if (defaultPlatformIcons.hasOwnProperty(type)) { + icon = defaultPlatformIcons[type].icon; + color = defaultPlatformIcons[type].color; + theme = defaultPlatformIcons[type].theme; + } + + return ( + + + + ); + } + // todo add filtering options + }, + { + title: 'Owner', + dataIndex: 'enrolmentInfo', + key: 'owner', + render: enrolmentInfo => enrolmentInfo.owner + // todo add filtering options + }, + { + title: 'Ownership', + dataIndex: 'enrolmentInfo', + key: 'ownership', + width: 100, + render: enrolmentInfo => enrolmentInfo.ownership + // todo add filtering options + }, + { + title: 'Status', + dataIndex: 'enrolmentInfo', + width: 100, + key: 'status', + render: (enrolmentInfo) => { + const status = enrolmentInfo.status.toLowerCase(); + let color = "#f9ca24"; + switch (status) { + case "active": + color = "#badc58"; + break; + case "created": + color = "#6ab04c"; + break; + case "removed": + color = "#ff7979"; + break; + case "inactive": + color = "#f9ca24"; + break; + case "blocked": + color = "#636e72"; + break; + } + return {status}; + } + // todo add filtering options + }, + { + title: 'Last Updated', + dataIndex: 'enrolmentInfo', + key: 'dateOfLastUpdate', + render: (data) => { + const {dateOfLastUpdate} = data; + const timeAgoString = getTimeAgo(dateOfLastUpdate); + return {timeAgoString}; + } + // todo add filtering options + } +]; + +const getTimeAgo = (time) => { + const timeAgo = new TimeAgo('en-US'); + return timeAgo.format(time); +}; + +class UsersDevices extends React.Component { + constructor(props) { + super(props); + config = this.props.context; + TimeAgo.addLocale(en); + this.state = { + data: [], + pagination: {}, + loading: false, + selectedRows: [] + }; + } + + rowSelection = { + onChange: (selectedRowKeys, selectedRows) => { + this.setState({ + selectedRows: selectedRows + }) + } + }; + + componentDidMount() { + this.fetch(); + } + + //Rerender component when parameters change + componentDidUpdate(prevProps, prevState, snapshot) { + if(prevProps.user !== this.props.user){ + this.fetch(); + } + } + + //fetch data from api + fetch = (params = {}) => { + const config = this.props.context; + this.setState({loading: true}); + // get current page + const currentPage = (params.hasOwnProperty("page")) ? params.page : 1; + + const extraParams = { + offset: 10 * (currentPage - 1), //calculate the offset + limit: 10, + user: this.props.user, + requireDeviceInfo: true, + }; + + const encodedExtraParams = Object.keys(extraParams) + .map(key => key + '=' + extraParams[key]).join('&'); + + //send request to the invoker + axios.get( + window.location.origin + config.serverConfig.invoker.uri + + config.serverConfig.invoker.deviceMgt + + "/devices?" + encodedExtraParams, + ).then(res => { + if (res.status === 200) { + const pagination = {...this.state.pagination}; + this.setState({ + loading: false, + data: res.data.data.devices, + pagination + }); + } + + }).catch((error) => { + if (error.hasOwnProperty("response") && error.response.status === 401) { + //todo display a popop with error + message.error('You are not logged in'); + window.location.href = window.location.origin + '/entgra/login'; + } else { + notification["error"]({ + message: "There was a problem", + duration: 0, + description: + "Error occurred while trying to load devices.", + }); + } + + this.setState({loading: false}); + }); + }; + + handleTableChange = (pagination, filters, sorter) => { + const pager = {...this.state.pagination}; + pager.current = pagination.current; + this.setState({ + pagination: pager, + }); + this.fetch({ + results: pagination.pageSize, + page: pagination.current, + sortField: sorter.field, + sortOrder: sorter.order, + ...filters, + }); + }; + + render() { + + const {data, pagination, loading, selectedRows} = this.state; + return ( +
+
(record.deviceIdentifier + record.enrolmentInfo.owner + record.enrolmentInfo.ownership)} + dataSource={data} + showHeader={false} + size="small" + pagination={{ + ...pagination, + size: "small", + // position: "top", + showTotal: (total, range) => `showing ${range[0]}-${range[1]} of ${total} devices` + // showQuickJumper: true + }} + loading={loading} + onChange={this.handleTableChange} + rowSelection={this.rowSelection} + /> + + ); + } +} + +export default withConfigContext(UsersDevices); \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersTable.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersTable.js new file mode 100644 index 0000000000..a1651111ff --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersTable.js @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from "react"; +import axios from "axios"; +import {message, notification, Table, Typography, Panel, Collapse, Button, List, Modal, Icon, Tabs} from "antd"; +import TimeAgo from 'javascript-time-ago' + +// Load locale-specific relative date/time formatting rules. +import en from 'javascript-time-ago/locale/en' +import {withConfigContext} from "../../context/ConfigContext"; +import DeviceTable from "../Devices/DevicesTable"; +import UsersDevices from "./UsersDevices"; + +const {Text} = Typography; + +let config = null; +let apiUrl; + +class UsersTable extends React.Component { + constructor(props) { + super(props); + config = this.props.context; + TimeAgo.addLocale(en); + this.state = { + data: [], + pagination: {}, + loading: false, + selectedRows: [], + rolesModalVisible: false, + rolesData: [], + user:'' + }; + } + + rowSelection = { + onChange: (selectedRowKeys, selectedRows) => { + this.setState({ + selectedRows: selectedRows + }) + } + }; + + componentDidMount() { + this.fetchUsers(); + } + + //fetch data from api + fetchUsers = (params = {}) => { + const config = this.props.context; + this.setState({loading: true}); + + // get current page + const currentPage = (params.hasOwnProperty("page")) ? params.page : 1; + + const extraParams = { + offset: 10 * (currentPage - 1), //calculate the offset + limit: 10, + }; + + const encodedExtraParams = Object.keys(extraParams) + .map(key => key + '=' + extraParams[key]).join('&'); + + apiUrl = window.location.origin + config.serverConfig.invoker.uri + + config.serverConfig.invoker.deviceMgt + + "/users?" + encodedExtraParams; + + //send request to the invokerss + axios.get(apiUrl).then(res => { + if (res.status === 200) { + const pagination = {...this.state.pagination}; + this.setState({ + loading: false, + data: res.data.data.users, + pagination, + }); + } + + }).catch((error) => { + if (error.hasOwnProperty("response") && error.response.status === 401) { + //todo display a popop with error + message.error('You are not logged in'); + window.location.href = window.location.origin + '/entgra/login'; + } else { + notification["error"]({ + message: "There was a problem", + duration: 0, + description:"Error occurred while trying to load users.", + }); + } + + this.setState({loading: false}); + }); + }; + + //fetch data from api + fetchRoles = (username) => { + const config = this.props.context; + + this.setState({ + rolesModalVisible: true, + user: username + }); + + apiUrl = window.location.origin + config.serverConfig.invoker.uri + + config.serverConfig.invoker.deviceMgt + + "/users/" + username + "/roles"; + + //send request to the invokerss + axios.get(apiUrl).then(res => { + if (res.status === 200) { + this.setState({ + rolesData: res.data.data.roles, + }); + } + + }).catch((error) => { + if (error.hasOwnProperty("response") && error.response.status === 401) { + //todo display a popop with error + message.error('You are not logged in'); + window.location.href = window.location.origin + '/entgra/login'; + } else { + notification["error"]({ + message: "There was a problem", + duration: 0, + description:"Error occurred while trying to load roles.", + }); + } + + this.setState({loading: false}); + }); + }; + + handleTableChange = (pagination, filters, sorter) => { + const pager = {...this.state.pagination}; + pager.current = pagination.current; + this.setState({ + pagination: pager, + }); + this.fetch({ + results: pagination.pageSize, + page: pagination.current, + sortField: sorter.field, + sortOrder: sorter.order, + ...filters, + }); + }; + + handleOk = e => { + this.setState({ + rolesModalVisible: false, + }); + }; + + handleCancel = e => { + this.setState({ + rolesModalVisible: false, + }); + }; + + render() { + const {data, pagination, loading, selectedRows} = this.state; + const { Panel } = Collapse; + const { TabPane } = Tabs; + const columns = [ + { + title: 'User Name', + dataIndex: 'username', + width: 150, + key: "username", + }, + { + title: 'First Name', + width: 150, + dataIndex: 'firstname', + key: 'firstname', + }, + { + title: 'Last Name', + width: 150, + dataIndex: 'lastname', + key: 'lastname', + }, + { + title: 'Email', + width: 100, + dataIndex: 'emailAddress', + key: 'emailAddress', + }, + { + title: '', + dataIndex: 'username', + key: 'roles', + render: (username) => + + } + ]; + return ( +
+
+
(record.username)} + dataSource={data} + pagination={{ + ...pagination, + size: "small", + // position: "top", + showTotal: (total, range) => `showing ${range[0]}-${range[1]} of ${total} groups` + // showQuickJumper: true + }} + loading={loading} + onChange={this.handleTableChange} + rowSelection={this.rowSelection} + /> + +
+ + + + + Roles + + } + key="1" + > + {item}} + /> + + + + Enrolled Devices + + } + key="2" + > + + + + +
+ + ); + } +} + +export default withConfigContext(UsersTable); \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js index b8206d16d7..8eeca9f07c 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js @@ -26,6 +26,11 @@ import './index.css'; import Devices from "./pages/Dashboard/Devices/Devices"; import Reports from "./pages/Dashboard/Reports/Reports"; import Geo from "./pages/Dashboard/Geo/Geo"; +import Groups from "./pages/Dashboard/Groups/Groups"; +import Users from "./pages/Dashboard/Users/Users"; +import Policies from "./pages/Dashboard/Policies/Policies"; +import Roles from "./pages/Dashboard/Roles/Roles"; +import DeviceTypes from "./pages/Dashboard/DeviceTypes/DeviceTypes"; const routes = [ { @@ -52,6 +57,31 @@ const routes = [ path: '/entgra/reports', component: Reports, exact: true + }, + { + path: '/entgra/groups', + component: Groups, + exact: true + }, + { + path: '/entgra/users', + component: Users, + exact: true + }, + { + path: '/entgra/policies', + component: Policies, + exact: true + }, + { + path: '/entgra/roles', + component: Roles, + exact: true + }, + { + path: '/entgra/devicetypes', + component: DeviceTypes, + exact: true } ] } diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.css b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.css index edb16b4c68..7923d0a9fc 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.css +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.css @@ -54,8 +54,11 @@ } .layout .logo-image img { - height: 32px; - margin: 16px; + height: 55px; + margin-top: 5px; + margin-left: 16px; + margin-right: 16px; + margin-bottom: 5px; } @media only screen and (min-width: 760px) { diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.js index 9a20fb39a8..138d70e094 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.js @@ -42,9 +42,11 @@ class Dashboard extends React.Component { mobileWidth }; this.logo = this.props.context.theme.logo; + this.config = this.props.context; } toggle = () => { + console.log(this.config) this.setState({ isNavBarCollapsed: !this.state.isNavBarCollapsed, }); @@ -63,8 +65,7 @@ class Dashboard extends React.Component { >
- logo - Entgra + logo
@@ -73,18 +74,61 @@ class Dashboard extends React.Component { Devices - - - - Geo - - + + + Geo + } + > + + + Single Device View + + + + + Device Group View + + + Reports + + + + Groups + + + + + + Users + + + + + + Policies + + + + + + Roles + + + + + + Device Types + + @@ -109,9 +153,8 @@ class Dashboard extends React.Component { title={ - - } - > + {this.config.user} + }> diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/DeviceTypes/DeviceTypes.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/DeviceTypes/DeviceTypes.js new file mode 100644 index 0000000000..de9625bcc1 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/DeviceTypes/DeviceTypes.js @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from "react"; +import { + PageHeader, + Typography, + Breadcrumb, + Icon +} from "antd"; +import {Link} from "react-router-dom"; +import DeviceTypesTable from "../../../components/DeviceTypes/DeviceTypesTable"; + +const {Paragraph} = Typography; + +class DeviceTypes extends React.Component { + routes; + + constructor(props) { + super(props); + this.routes = props.routes; + } + + render() { + return ( +
+ + + + Home + + Device Types + +
+

Device Types

+ All device types for device management. +
+
+ +
+
+
+ +
+
+ ); + } +} + +export default DeviceTypes; diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Devices/Devices.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Devices/Devices.js index f78f1c89f9..3adf87207c 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Devices/Devices.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Devices/Devices.js @@ -49,8 +49,7 @@ class Devices extends React.Component {

Devices

- Lorem ipsum dolor sit amet, est similique constituto at, quot inermis id mel, an - illud incorrupte nam. + All enrolled devices
diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Groups/Groups.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Groups/Groups.js new file mode 100644 index 0000000000..b96f869872 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Groups/Groups.js @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from "react"; +import { + PageHeader, + Typography, + Breadcrumb, + Icon +} from "antd"; +import {Link} from "react-router-dom"; +import GroupsTable from "../../../components/Groups/GroupsTable"; + +const {Paragraph} = Typography; + +class Groups extends React.Component { + routes; + + constructor(props) { + super(props); + this.routes = props.routes; + } + + render() { + return ( +
+ + + + Home + + Groups + +
+

Groups

+ All device groups. +
+
+ +
+
+
+ +
+
+ ); + } +} + +export default Groups; diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Policies/Policies.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Policies/Policies.js new file mode 100644 index 0000000000..7c32b7a0a2 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Policies/Policies.js @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from "react"; +import { + PageHeader, + Typography, + Breadcrumb, + Icon +} from "antd"; +import {Link} from "react-router-dom"; +import PoliciesTable from "../../../components/Policies/PoliciesTable"; + +const {Paragraph} = Typography; + +class Policies extends React.Component { + routes; + + constructor(props) { + super(props); + this.routes = props.routes; + } + + render() { + return ( +
+ + + + Home + + Policies + +
+

Policies

+ All policies for device management +
+
+ +
+
+
+ +
+
+ ); + } +} + +export default Policies; diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Roles/Roles.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Roles/Roles.js new file mode 100644 index 0000000000..03a8f5e78f --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Roles/Roles.js @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from "react"; +import { + PageHeader, + Typography, + Breadcrumb, + Icon +} from "antd"; +import {Link} from "react-router-dom"; +import RolesTable from "../../../components/Roles/RolesTable"; + +const {Paragraph} = Typography; + +class Roles extends React.Component { + routes; + + constructor(props) { + super(props); + this.routes = props.routes; + } + + render() { + return ( +
+ + + + Home + + Roles + +
+

Roles

+ All user roles +
+
+ +
+
+
+ +
+
+ ); + } +} + +export default Roles; diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Users/Users.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Users/Users.js new file mode 100644 index 0000000000..dcd9a1d0f8 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Users/Users.js @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from "react"; +import { + PageHeader, + Typography, + Breadcrumb, + Icon +} from "antd"; +import {Link} from "react-router-dom"; +import UsersTable from "../../../components/Users/UsersTable"; + +const {Paragraph} = Typography; + +class Users extends React.Component { + routes; + + constructor(props) { + super(props); + this.routes = props.routes; + } + + render() { + return ( +
+ + + + Home + + Users + +
+

Users

+ All users for device management. +
+
+ +
+
+
+ +
+
+ ); + } +} + +export default Users; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/device/details/DeviceLocation.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/device/details/DeviceLocation.java index 71270b1683..09ae42117c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/device/details/DeviceLocation.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/device/details/DeviceLocation.java @@ -56,45 +56,29 @@ public class DeviceLocation implements Serializable { @ApiModelProperty(name = "updatedTime", value = "Update time of the device.", required = true) private Date updatedTime; @ApiModelProperty(name = "altitude", value = "Device altitude.", required = true) - private Double altitude; + private double altitude; @ApiModelProperty(name = "speed", value = "Device speed.", required = true) - private Float speed; + private float speed; @ApiModelProperty(name = "bearing", value = "Device bearing.", required = true) - private Float bearing; + private float bearing; @ApiModelProperty(name = "distance", value = "Device distance.", required = true) - private Double distance; + private double distance; - public Double getDistance() { - return distance; - } + public double getAltitude() { return altitude; } - public void setDistance(Double distance) { - this.distance = distance; - } + public void setAltitude(double altitude) { this.altitude = altitude; } - public Double getAltitude() { - return altitude; - } + public float getSpeed() { return speed; } - public Float getSpeed() { - return speed; - } + public void setSpeed(float speed) { this.speed = speed; } - public void setSpeed(Float speed) { - this.speed = speed; - } + public float getBearing() { return bearing; } - public Float getBearing() { - return bearing; - } + public void setBearing(float bearing) { this.bearing = bearing; } - public void setBearing(Float bearing) { - this.bearing = bearing; - } + public double getDistance() { return distance; } - public void setAltitude(Double altitude) { - this.altitude = altitude; - } + public void setDistance(double distance) { this.distance = distance; } public int getDeviceId() { return deviceId; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java index 6e30b52c3f..a012fff0c8 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java @@ -3712,7 +3712,6 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv log.debug("Getting all devices details for device ids: " + devicesIds); } PaginationResult paginationResult = new PaginationResult(); - int count; List subscribedDeviceDetails; try { DeviceManagementDAOFactory.openConnection(); @@ -3722,12 +3721,11 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv paginationResult.setData(new ArrayList<>()); paginationResult.setRecordsFiltered(0); paginationResult.setRecordsTotal(0); + return paginationResult; } - count = deviceDAO.getSubscribedDeviceCount(devicesIds, tenantId, status); - paginationResult.setData(getAllDeviceInfo(subscribedDeviceDetails)); + int count = deviceDAO.getSubscribedDeviceCount(devicesIds, tenantId, status); paginationResult.setRecordsFiltered(count); paginationResult.setRecordsTotal(count); - return paginationResult; } catch (DeviceManagementDAOException e) { String msg = "Error occurred while retrieving device list for device ids " + devicesIds; log.error(msg, e); @@ -3739,6 +3737,8 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv } finally { DeviceManagementDAOFactory.closeConnection(); } + paginationResult.setData(getAllDeviceInfo(subscribedDeviceDetails)); + return paginationResult; } /** diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.navbar.nav-menu/nav-menu.hbs b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.navbar.nav-menu/nav-menu.hbs index 8c80bd6fc7..b071abf81d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.navbar.nav-menu/nav-menu.hbs +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.navbar.nav-menu/nav-menu.hbs @@ -118,7 +118,7 @@ {{/if}} {{#if iosPluginFlag}}
  • - + DEP Configurations