Compare commits

Invalid templates have been ignored

1 invalid template(s) found pull_request_template.md: frontmatter must start with a separator line

...

90 Commits

Author SHA1 Message Date
Lasantha Dharmakeerthi 3066e51354 Show device identifier and delete certificate using certificate Id
1 year ago
Inosh Perara 8907903e26 Merge pull request 'Retrieve app details of Operation' (#203) from osh.silva/device-mgt-core:app-install-9211 into master
1 year ago
osh 74d4e2dded Add vpp scopes
1 year ago
osh 81e57ce78f Retrieve extra details
1 year ago
osh 1d712e1bc2 Merge branch 'master' of ssh://repository.entgra.net:222/community/device-mgt-core into app-install-9211
1 year ago
osh e2a467bc45 Update activity loading
1 year ago
Inosh Perara f87f742262 Merge pull request 'Revert temp fix done for Windows enrollment and add missing enroll scope' (#202) from navodzoysa/device-mgt-core:issue-10235/windows-auth into master
1 year ago
osh 9fa34a32af Resolve conflicts
1 year ago
osh e6ee539239 Add api changes for getting app details of operation
1 year ago
Navod Zoysa 607b11a224 Add missing Windows enroll scope
1 year ago
Navod Zoysa 453034c0e2 Revert Windows permission temp fix
1 year ago
Pahansith Gunathilake 19ec02828e Merge pull request 'Merge vpp-v2 changes to master' (#200) from osh.silva/device-mgt-core:vpp-v2 into master
1 year ago
osh 90a513590e Merge branch 'master' of ssh://repository.entgra.net:222/community/device-mgt-core into vpp-v2
1 year ago
Inosh Perara 30430712cf Merge pull request 'Add get device apps by id service' (#184) from osh.silva/device-mgt-core:device-apps-api-1 into master
1 year ago
osh 4635e2bd14 Merge branch 'master' of ssh://repository.entgra.net:222/community/device-mgt-core into device-apps-api-1
1 year ago
osh a20c5a723c Merge branch 'master' of ssh://repository.entgra.net:222/community/device-mgt-core into vpp-v2
1 year ago
Amalka Subasinghe 2dcb65bc35 Merge pull request 'fixed build break' (#197) from amalka.subasinghe/device-mgt-core:master into master
1 year ago
Amalka Subasinghe 0375eab755 fixed build break
1 year ago
Lasantha Dharmakeerthi b11c932814 Notify cluster formation changed implementation
1 year ago
Lasantha Dharmakeerthi 80adbe665a WS token generator
1 year ago
Amalka Subasinghe f33e104755 refactor oauth2 token generator
1 year ago
Amalka Subasinghe 35f11a0d94 ws token generator
1 year ago
Lasantha Dharmakeerthi e87d4b5036 Fix WS API publishing and dynamic endpoint configurations
1 year ago
Amalka Subasinghe 7de0e1aabd fixed merge conflict
1 year ago
Lasantha Dharmakeerthi 7007e1894b Improve check API revision deployment list length logic
1 year ago
Charitha Goonetilleke 462669e3ec Merge branch 'master' into master
1 year ago
Pasindu Rupasinghe 7d859a317c Improve check revision deployment list length logic
1 year ago
Amalka Subasinghe c6c2ef9a01 fixed ws api publishing and dynamic endpoint configurations
1 year ago
builder fabd3ebae8 [maven-release-plugin] prepare for next development iteration
1 year ago
builder 02458cc4fe [maven-release-plugin] prepare release v5.0.28
1 year ago
Pahansith Gunathilake bfd260e6f9 Merge pull request 'Fix issues with retrieving visible roles' (#191) from prathabanKavin/device-mgt-core:visiblefix into master
1 year ago
prathabanKavin f091d26f9c Fix issues with retrieving visible roles
1 year ago
Pahansith Gunathilake a8badb22c4 Merge pull request 'Fix for visible role issue' (#190) from prathabanKavin/device-mgt-core:visiblerolefix into master
1 year ago
prathabanKavin 20906122db Fix for visible role issue
1 year ago
Kavin Prathaban 1921b3e54d Add missing device identifier column to dbscripts (#189)
1 year ago
Pahansith Gunathilake 8011170379 Fix issue in tenant id not append to certificate subject (#188)
1 year ago
osh 4436c48228 Merge branch 'master' of ssh://repository.entgra.net:222/community/device-mgt-core into device-apps-api-1
1 year ago
Amalka Subasinghe 66f33f4845 notify cluster formation changed nug fixes
1 year ago
Amalka Subasinghe 615da6303f notify cluster formation changed implementation
1 year ago
builder f19f48d050 [maven-release-plugin] prepare for next development iteration
1 year ago
builder ff9971ed77 [maven-release-plugin] prepare release v5.0.27
1 year ago
Rajitha Kumara 7c9d3a2108 Fixes for grouping issues (#186)
1 year ago
osh 77b68af5d0 Add pagination
1 year ago
osh e7b0255a95 Add get device apps by id service
1 year ago
Inosh Perara 8d552b3070 Merge pull request 'Add VPP token field' (#182) from osh.silva/device-mgt-core:vpp-token-change-10156 into vpp-v2
1 year ago
osh 4b9cad1c75 Update db queries
1 year ago
osh 32a289e10e Merge branch 'vpp-v2' of ssh://repository.entgra.net:222/community/device-mgt-core into vpp-token-change-10156
1 year ago
osh dd7910268e Add vpp token field
1 year ago
osh b576f3d9bb Merge branch 'master' of ssh://repository.entgra.net:222/community/device-mgt-core into vpp-v2
1 year ago
Inosh Perara ec88734831 Merge pull request 'Add db scripts for VPP feature' (#179) from osh.silva/device-mgt-core:vpp-db-scripts into vpp-v2
1 year ago
Inosh Perara 2dd3e86f69 Merge pull request 'Grouping Issues' (#181) from ThilinaPremachandra/device-mgt-core:groupingIssues into master
1 year ago
Thilina Sandaruwan 6dbad29776 fix: role sharing issues for other users
1 year ago
osh cd17d06158 Merge branch 'master' of ssh://repository.entgra.net:222/community/device-mgt-core into vpp-v2
1 year ago
Charitha Goonetilleke 3d5fce400b Merge pull request 'Rearrange getOperations by eliminating the necessity of the owner param' (#170) from Sasini_Sandamali/device-mgt-core:master into master
1 year ago
Charitha Goonetilleke 6e1e58f2ec Merge branch 'master' into master
1 year ago
osh 2249520132 Resolve conflicts
1 year ago
osh 01df370032 Add db scripts
1 year ago
Inosh Perara fefc66bc59 Merge pull request 'Improve update asset DAO' (#174) from osh.silva/device-mgt-core:vpp-daos into vpp-v2
1 year ago
Lasantha Dharmakeerthi 0b0d2e620f Fix class not found error in Grafana component
1 year ago
Navod Zoysa 90741dc502 Fix class not found error in analytics component
1 year ago
Inosh Perara 374be8bc25 Merge pull request 'Add missing ios scopes in mdm-ui-config' (#173) from prathabanKavin/device-mgt-core:mdmconfigfix into master
1 year ago
osh eb740773aa Improve update asset DAO
1 year ago
prathabanKavin a0d6c2bd21 Add missing ios scopes in mdm-ui-config
1 year ago
Inosh Perara b3a4649b64 Merge pull request 'Add DAO Layer for VPP Associate' (#168) from osh.silva/device-mgt-core:vpp-associate into vpp-v2
1 year ago
Sasini Sandamali b9ecb8ce40 Rearrange getOperations by eliminating the necessity of the owner param
1 year ago
Thilina Sandaruwan 38b8c8d7b1 Grouping Improvements (#169)
1 year ago
osh 81fd5687ef Update user service and token retrieval
1 year ago
Thilina Sandaruwan 253dc03233 fix: deleted roles removing issue
1 year ago
Thilina Sandaruwan 907043fd91 Merge branch 'master'
1 year ago
osh dae8c09761 Resolve comments
1 year ago
osh b978e31ab0 Resolve conflicts
1 year ago
osh 0e5478fb5e Add association DAO and fix meta issue
1 year ago
Inosh Perara 8507a88cad Merge pull request 'Add DAO improvements for user APIs' (#166) from inosh/device-mgt-core:vpp into vpp-v2
1 year ago
inoshperera 026986cd93 Add DAO improvements for user APIs
1 year ago
Thilina Sandaruwan 6c645db486 add: proper msg for group delete
1 year ago
Inosh Perara 949fbef41b Merge pull request 'Add DAOs for asset management' (#162) from osh.silva/device-mgt-core:asset-dao-10179 into vpp-v2
1 year ago
osh c9ed09ee25 Resolve conflicts
1 year ago
Inosh Perara a69218d436 Merge pull request 'Add association apis' (#161) from inosh/device-mgt-core:vpp into vpp-v2
1 year ago
osh 1263c09079 Add DAOs for asset management
1 year ago
inoshperera 54111b4d94 Add association apis
1 year ago
Inosh Perara caa9959dcd Merge pull request 'Add asset apis' (#156) from inosh/device-mgt-core:vpp into vpp-v2
1 year ago
inoshperera 61ffd4abff Fixing conflics
1 year ago
Inosh Perara fa565eb1ea Merge pull request 'Adding the DAO layer for vpp user management' (#155) from osh.silva/device-mgt-core:vpp-user-dao-10169 into vpp-v2
1 year ago
osh 2e799a545f Resolve comments
1 year ago
inoshperera 665702d504 Add asset apis
1 year ago
osh cd42a2c48f Adding the DAO layer for vpp user management
1 year ago
Inosh Perara f246d6b8de Merge pull request 'add vpp user services' (#151) from inosh/device-mgt-core:vpp into vpp-v2
1 year ago
inoshperera cc8470d3c0 add vpp user services
1 year ago
Inosh Perara 9dd24eda17 Merge pull request 'Add vpp user apis' (#147) from inosh/device-mgt-core:vpp into vpp-v2
1 year ago
inoshperera 9ccf3a5fa5 Add vpp user apis
1 year ago

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>grafana-mgt</artifactId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,11 +22,11 @@ import com.google.gson.JsonObject;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api.GrafanaAPIProxyService;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api.bean.ErrorResponse;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api.exception.RefererNotValid;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api.impl.util.GrafanaMgtAPIUtils;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api.impl.util.GrafanaRequestHandlerUtil;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.common.exception.GrafanaManagementException;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.bean.GrafanaPanelIdentifier;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.exception.MaliciousQueryAttempt;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.internal.GrafanaMgtDataHolder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DBConnectionException;
@ -57,8 +57,8 @@ public class GrafanaAPIProxyServiceImpl implements GrafanaAPIProxyService {
public Response queryDatasource(JsonObject body, @Context HttpHeaders headers, @Context UriInfo requestUriInfo) {
try {
GrafanaPanelIdentifier panelIdentifier = GrafanaRequestHandlerUtil.getPanelIdentifier(headers);
GrafanaMgtDataHolder.getInstance().getGrafanaQueryService().
buildSafeQuery(body, panelIdentifier.getDashboardId(), panelIdentifier.getPanelId(), requestUriInfo.getRequestUri());
GrafanaMgtAPIUtils.getGrafanaQueryService().buildSafeQuery(body, panelIdentifier.getDashboardId(),
panelIdentifier.getPanelId(), requestUriInfo.getRequestUri());
return GrafanaRequestHandlerUtil.proxyPassPostRequest(body, requestUriInfo, panelIdentifier.getOrgId());
} catch (MaliciousQueryAttempt e) {
return Response.status(Response.Status.BAD_REQUEST).entity(

@ -0,0 +1,52 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api.impl.util;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.service.GrafanaQueryService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
public class GrafanaMgtAPIUtils {
private static final Log log = LogFactory.getLog(GrafanaMgtAPIUtils.class);
private static volatile GrafanaQueryService grafanaQueryService;
/**
* Accessing GrafanaQueryService from OSGI service context
* @return GrafanaQueryService instance
*/
public static GrafanaQueryService getGrafanaQueryService() {
if (grafanaQueryService == null) {
synchronized (GrafanaMgtAPIUtils.class) {
if (grafanaQueryService == null) {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
grafanaQueryService =
(GrafanaQueryService) ctx.getOSGiService(GrafanaQueryService.class, null);
if (grafanaQueryService == null) {
String msg = "Grafana Query service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
}
}
}
return grafanaQueryService;
}
}

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>grafana-mgt</artifactId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>grafana-mgt</artifactId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -88,7 +88,7 @@
io.entgra.device.mgt.core.application.mgt.core.*
</Import-Package>
<Export-Package>
!io.entgra.device.mgt.core.transport.mgt.email.sender.core.internal,
!io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.internal,
io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.*
</Export-Package>
<Embed-Dependency>

@ -26,7 +26,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.framework.BundleContext;
import org.osgi.service.component.ComponentContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
/**
* @scr.component name="io.entgra.analytics.mgt.grafana.proxy.grafanamanagementservicecomponent" immediate="true"

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>analytics-mgt</artifactId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>io.entgra.device.mgt.core.parent</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -20,7 +20,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -22,7 +22,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -24,13 +24,12 @@ import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.APIService
import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.BadRequestException;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.UnexpectedResponseException;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.APIInfo;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Scope;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Mediation;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Documentation;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.APIRevision;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.APIRevisionDeployment;
import org.json.JSONObject;
import org.wso2.carbon.apimgt.api.model.APIIdentifier;
import org.wso2.carbon.apimgt.api.model.Scope;
import org.wso2.carbon.apimgt.api.model.Mediation;
import org.wso2.carbon.apimgt.api.model.APIRevision;
import org.wso2.carbon.apimgt.api.model.APIRevisionDeployment;
import org.wso2.carbon.apimgt.api.model.Documentation;
import java.util.List;
@ -48,7 +47,7 @@ public interface PublisherRESTAPIServices {
boolean updateSharedScope(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, Scope scope)
throws APIServicesException, BadRequestException, UnexpectedResponseException;
JSONObject getApi(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, APIIdentifier apiIdentifier)
JSONObject getApi(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, String apiUuid)
throws APIServicesException, BadRequestException, UnexpectedResponseException;
JSONObject getApis(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo)
@ -65,15 +64,15 @@ public interface PublisherRESTAPIServices {
throws APIServicesException, BadRequestException, UnexpectedResponseException;
JSONObject getAllApiSpecificMediationPolicies(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
APIIdentifier apiIdentifier)
String apiUuid)
throws APIServicesException, BadRequestException, UnexpectedResponseException;
boolean addApiSpecificMediationPolicy(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
String uuid, Mediation mediation)
throws APIServicesException, BadRequestException, UnexpectedResponseException;
boolean updateApiSpecificMediationPolicyContent(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
String uuid, Mediation mediation)
boolean deleteApiSpecificMediationPolicy(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
String uuid, Mediation mediation)
throws APIServicesException, BadRequestException, UnexpectedResponseException;
boolean changeLifeCycleStatus(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
@ -108,11 +107,11 @@ public interface PublisherRESTAPIServices {
String uuid, String documentID)
throws APIServicesException, BadRequestException, UnexpectedResponseException;
Documentation addDocumentation(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Documentation addDocumentation(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
String uuid, Documentation documentation)
throws APIServicesException, BadRequestException, UnexpectedResponseException;
boolean addDocumentationContent(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
APIInfo api, String docId, String docContent)
String apiUuid, String docId, String docContent)
throws APIServicesException, BadRequestException, UnexpectedResponseException;
}

@ -21,30 +21,26 @@ package io.entgra.device.mgt.core.apimgt.extension.rest.api;
import com.google.gson.Gson;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.constants.Constants;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIApplicationKey;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.APIInfo;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Scope;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Mediation;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Documentation;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.APIRevision;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.APIRevisionDeployment;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.AccessTokenInfo;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.APIServicesException;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.BadRequestException;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.UnexpectedResponseException;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.APIInfo;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.util.HttpsTrustManagerUtils;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.util.ScopeUtils;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.RequestBody;
import okhttp3.*;
import okhttp3.Request.Builder;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.ssl.Base64;
import org.json.JSONArray;
import org.json.JSONObject;
import org.wso2.carbon.apimgt.api.model.APIIdentifier;
import org.wso2.carbon.apimgt.api.model.Scope;
import org.wso2.carbon.apimgt.api.model.Mediation;
import org.wso2.carbon.apimgt.api.model.APIRevision;
import org.wso2.carbon.apimgt.api.model.APIRevisionDeployment;
import org.wso2.carbon.apimgt.api.model.Documentation;
import java.io.IOException;
import java.util.List;
@ -237,10 +233,10 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices {
}
@Override
public JSONObject getApi(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, APIIdentifier apiIdentifier)
public JSONObject getApi(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo, String apiUuid)
throws APIServicesException, BadRequestException, UnexpectedResponseException {
String getAllApi = endPointPrefix + Constants.API_ENDPOINT + apiIdentifier.getUUID();
String getAllApi = endPointPrefix + Constants.API_ENDPOINT + apiUuid;
Request request = new Request.Builder()
.url(getAllApi)
.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER
@ -259,7 +255,7 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices {
generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(),
apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret());
//TODO: max attempt count
return getApi(apiApplicationKey, refreshedAccessToken, apiIdentifier);
return getApi(apiApplicationKey, refreshedAccessToken, apiUuid);
} else if (HttpStatus.SC_BAD_REQUEST == response.code()) {
String msg = "Bad Request, Invalid request";
log.error(msg);
@ -344,6 +340,7 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices {
" \"apiThrottlingPolicy\": " + api.getApiThrottlingPolicy() + ",\n" +
" \"authorizationHeader\": \"" + api.getAuthorizationHeader() + "\",\n" +
" \"visibility\": \"" + api.getVisibility() + "\",\n" +
" \"mediationPolicies\": " + (api.getInSequence() != null ? "[{\"name\": \"" + api.getInSequence() + "\",\"type\": \"in\"}]" : null) + ",\n" +
" \"subscriptionAvailability\": \"" + api.getSubscriptionAvailability() + "\",\n" +
" \"subscriptionAvailableTenants\": [],\n" +
" \"additionalProperties\": [],\n" +
@ -359,7 +356,7 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices {
" \"endpointConfig\": " + api.getEndpointConfig().toString() + ",\n" +
" \"endpointImplementationType\": \"ENDPOINT\",\n" +
" \"scopes\": " + api.getScopes().toString() + ",\n" +
" \"operations\": " + api.getOperations().toString() + ",\n" +
" \"operations\": " + (api.getOperations() != null ? api.getOperations().toString() : null) + ",\n" +
" \"threatProtectionPolicies\": null,\n" +
" \"categories\": [],\n" +
" \"keyManagers\": " + gson.toJson(api.getKeyManagers()) + ",\n" +
@ -431,6 +428,7 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices {
" \"apiThrottlingPolicy\": " + api.getApiThrottlingPolicy() + ",\n" +
" \"authorizationHeader\": \"" + api.getAuthorizationHeader() + "\",\n" +
" \"visibility\": \"" + api.getVisibility() + "\",\n" +
" \"mediationPolicies\": " + (api.getInSequence() != null ? "[{\"name\": \"" + api.getInSequence() + "\",\"type\": \"in\"}]" : null) + ",\n" +
" \"subscriptionAvailability\": \"" + api.getSubscriptionAvailability() + "\",\n" +
" \"subscriptionAvailableTenants\": [],\n" +
" \"additionalProperties\": [],\n" +
@ -446,7 +444,7 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices {
" \"endpointConfig\": " + api.getEndpointConfig().toString() + ",\n" +
" \"endpointImplementationType\": \"ENDPOINT\",\n" +
" \"scopes\": " + api.getScopes().toString() + ",\n" +
" \"operations\": " + api.getOperations().toString() + ",\n" +
" \"operations\": " + (api.getOperations() != null? api.getOperations().toString() : null) + ",\n" +
" \"threatProtectionPolicies\": null,\n" +
" \"categories\": [],\n" +
" \"keyManagers\": " + gson.toJson(api.getKeyManagers()) + ",\n" +
@ -493,11 +491,16 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices {
String uuid, String asyncApiDefinition)
throws APIServicesException, BadRequestException, UnexpectedResponseException {
String addNewScope = endPointPrefix + Constants.API_ENDPOINT + uuid;
String saveAsyncAPI = endPointPrefix + Constants.API_ENDPOINT + uuid + "/asyncapi";
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("apiDefinition", asyncApiDefinition)
.build();
RequestBody requestBody = RequestBody.create(JSON, asyncApiDefinition);
Request request = new Request.Builder()
.url(addNewScope)
.url(saveAsyncAPI)
.addHeader(Constants.HEADER_CONTENT_TYPE, "multipart/form-data")
.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER
+ accessTokenInfo.getAccess_token())
.put(requestBody)
@ -532,10 +535,10 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices {
@Override
public JSONObject getAllApiSpecificMediationPolicies(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
APIIdentifier apiIdentifier)
String apiUuid)
throws APIServicesException, BadRequestException, UnexpectedResponseException {
String getAPIMediationEndPoint = endPointPrefix + Constants.API_ENDPOINT + apiIdentifier.getUUID() + "/mediation-policies";
String getAPIMediationEndPoint = endPointPrefix + Constants.API_ENDPOINT + apiUuid + "/mediation-policies";
Request request = new Request.Builder()
.url(getAPIMediationEndPoint)
.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER
@ -554,7 +557,7 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices {
generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(),
apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret());
//TODO: max attempt count
return getAllApiSpecificMediationPolicies(apiApplicationKey, refreshedAccessToken, apiIdentifier);
return getAllApiSpecificMediationPolicies(apiApplicationKey, refreshedAccessToken, apiUuid);
} else if (HttpStatus.SC_BAD_REQUEST == response.code()) {
String msg = "Bad Request, Invalid request";
log.error(msg);
@ -575,12 +578,17 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices {
String uuid, Mediation mediation)
throws APIServicesException, BadRequestException, UnexpectedResponseException {
String addAPIMediation = endPointPrefix + Constants.API_ENDPOINT + uuid + "/mediation-policies/" + mediation.getUuid()
+ "/content";
String addAPIMediation = endPointPrefix + Constants.API_ENDPOINT + uuid + "/mediation-policies";
RequestBody requestBody = RequestBody.create(JSON, String.valueOf(mediation));
Request request = new Request.Builder()
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("inlineContent", mediation.getConfig())
.addFormDataPart("type", mediation.getType())
.build();
Request request = new Builder()
.url(addAPIMediation)
.addHeader(Constants.HEADER_CONTENT_TYPE, "multipart/form-data")
.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER
+ accessTokenInfo.getAccess_token())
.post(requestBody)
@ -613,26 +621,23 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices {
}
@Override
public boolean updateApiSpecificMediationPolicyContent(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
public boolean deleteApiSpecificMediationPolicy(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
String uuid, Mediation mediation)
throws APIServicesException, BadRequestException, UnexpectedResponseException {
String updateApiMediationEndPOint = endPointPrefix + Constants.API_ENDPOINT + uuid + "/mediation-policies/" + mediation.getUuid()
+ "/content";
String deleteApiMediationEndPOint = endPointPrefix + Constants.API_ENDPOINT + uuid + "/mediation-policies/" + mediation.getUuid();
RequestBody requestBody = RequestBody.create(JSON, String.valueOf(mediation));
Request request = new Request.Builder()
.url(updateApiMediationEndPOint)
.url(deleteApiMediationEndPOint)
.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER
+ accessTokenInfo.getAccess_token())
.put(requestBody)
.delete()
.build();
try {
Response response = client.newCall(request).execute();
if (HttpStatus.SC_CREATED == response.code()) { // Check response status
if (HttpStatus.SC_NO_CONTENT == response.code()) { // Check response status
return true;
} else if (HttpStatus.SC_UNAUTHORIZED == response.code()) {
APIApplicationServices apiApplicationServices = new APIApplicationServicesImpl();
@ -640,7 +645,7 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices {
generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(),
apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret());
//TODO: max attempt count
return updateApiSpecificMediationPolicyContent(apiApplicationKey, refreshedAccessToken, uuid, mediation);
return deleteApiSpecificMediationPolicy(apiApplicationKey, refreshedAccessToken, uuid, mediation);
} else if (HttpStatus.SC_BAD_REQUEST == response.code()) {
String msg = "Bad Request, Invalid mediation policy";
log.error(msg);
@ -1018,18 +1023,19 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices {
String addNewScope = endPointPrefix + Constants.API_ENDPOINT + uuid + "/documents";
String document = "{\n" +
" \"name\": \" " + documentation.getName() + " \",\n" +
" \"type\": \" " + documentation.getType() + " \",\n" +
" \"summary\": \" " + documentation.getSummary() + " \",\n" +
" \"sourceType\": \" " + documentation.getSourceType() + " \",\n" +
" \"inlineContent\": \" " + documentation.getSourceType() + " \",\n" +
" \"visibility\": \" " + documentation.getVisibility() + " \",\n" +
" \"createdBy\": \" admin \"\n" +
" \"name\": \"" + documentation.getName() + "\",\n" +
" \"type\": \"" + documentation.getType() + "\",\n" +
" \"summary\": \"" + documentation.getSummary() + "\",\n" +
" \"sourceType\": \"" + documentation.getSourceType() + "\",\n" +
" \"inlineContent\": \"" + documentation.getSourceType() + "\",\n" +
" \"visibility\": \"" + documentation.getVisibility() + "\",\n" +
" \"createdBy\": \"admin\"\n" +
"}";
RequestBody requestBody = RequestBody.create(JSON, document);
Request request = new Request.Builder()
.url(addNewScope)
.addHeader(Constants.HEADER_CONTENT_TYPE, Constants.APPLICATION_JSON)
.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER
+ accessTokenInfo.getAccess_token())
.post(requestBody)
@ -1063,14 +1069,19 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices {
@Override
public boolean addDocumentationContent(APIApplicationKey apiApplicationKey, AccessTokenInfo accessTokenInfo,
APIInfo api, String docId, String docContent)
String apiUuid, String docId, String docContent)
throws APIServicesException, BadRequestException, UnexpectedResponseException {
String addDocumentationContentEndPoint = endPointPrefix + Constants.API_ENDPOINT + api.getId() + "/documents/" + docId;
String addDocumentationContentEndPoint = endPointPrefix + Constants.API_ENDPOINT + apiUuid + "/documents/" + docId + "/content";
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("inlineContent", docContent)
.build();
RequestBody requestBody = RequestBody.create(JSON, docContent);
Request request = new Request.Builder()
.url(addDocumentationContentEndPoint)
.addHeader(Constants.HEADER_CONTENT_TYPE, "multipart/form-data")
.addHeader(Constants.AUTHORIZATION_HEADER_NAME, Constants.AUTHORIZATION_HEADER_PREFIX_BEARER
+ accessTokenInfo.getAccess_token())
.post(requestBody)
@ -1086,7 +1097,7 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices {
generateAccessTokenFromRefreshToken(accessTokenInfo.getRefresh_token(),
apiApplicationKey.getClientId(), apiApplicationKey.getClientSecret());
//TODO: max attempt count
return addDocumentationContent(apiApplicationKey, refreshedAccessToken, api, docId, docContent);
return addDocumentationContent(apiApplicationKey, refreshedAccessToken, apiUuid, docId, docContent);
} else if (HttpStatus.SC_BAD_REQUEST == response.code()) {
String msg = "Bad Request, Invalid documentation request body";
log.error(msg);

@ -1,12 +1,12 @@
/*
* Copyright (c) 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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
@ -19,13 +19,8 @@
package io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo;
import org.json.JSONObject;
import org.wso2.carbon.apimgt.api.model.APICategory;
import org.wso2.carbon.apimgt.api.model.CORSConfiguration;
import org.wso2.carbon.apimgt.api.model.WebsubSubscriptionConfiguration;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.*;
/**
* This class represents the API response.
@ -70,7 +65,6 @@ public class APIInfo {
private String accessControlRoles;
private BusinessInformation businessInformation;
private CORSConfiguration corsConfiguration;
private WebsubSubscriptionConfiguration websubSubscriptionConfiguration;
private String workflowStatus;
private String createdTime;
private String lastUpdatedTime;
@ -79,11 +73,16 @@ public class APIInfo {
private List<JSONObject> scopes = new ArrayList();
private List<JSONObject> operations;
private String threatProtectionPolicies;
private List<APICategory> apiCategories;
private List<String> keyManagers = new ArrayList();
private JSONObject serviceInfo = new JSONObject();
private AdvertiseInfo advertiseInfo;
private String asyncApiDefinition;
private Set<URITemplate> uriTemplates = new LinkedHashSet<URITemplate>();
private String inSequence;
private Map<String, String> wsUriMapping;
public String getId() {
return id;
}
@ -372,14 +371,6 @@ public class APIInfo {
this.corsConfiguration = corsConfiguration;
}
public WebsubSubscriptionConfiguration getWebsubSubscriptionConfiguration() {
return websubSubscriptionConfiguration;
}
public void setWebsubSubscriptionConfiguration(WebsubSubscriptionConfiguration websubSubscriptionConfiguration) {
this.websubSubscriptionConfiguration = websubSubscriptionConfiguration;
}
public String getWorkflowStatus() {
return workflowStatus;
}
@ -444,14 +435,6 @@ public class APIInfo {
this.threatProtectionPolicies = threatProtectionPolicies;
}
public List<APICategory> getApiCategories() {
return apiCategories;
}
public void setApiCategories(List<APICategory> apiCategories) {
this.apiCategories = apiCategories;
}
public List<String> getKeyManagers() {
return keyManagers;
}
@ -475,4 +458,36 @@ public class APIInfo {
public void setAdvertiseInfo(AdvertiseInfo advertiseInfo) {
this.advertiseInfo = advertiseInfo;
}
public String getInSequence() {
return inSequence;
}
public void setInSequence(String inSequence) {
this.inSequence = inSequence;
}
public String getAsyncApiDefinition() {
return asyncApiDefinition;
}
public void setAsyncApiDefinition(String asyncApiDefinition) {
this.asyncApiDefinition = asyncApiDefinition;
}
public Set<URITemplate> getUriTemplates() {
return uriTemplates;
}
public void setUriTemplates(Set<URITemplate> uriTemplates) {
this.uriTemplates = uriTemplates;
}
public Map<String, String> getWsUriMapping() {
return wsUriMapping;
}
public void setWsUriMapping(Map<String, String> wsUriMapping) {
this.wsUriMapping = wsUriMapping;
}
}

@ -0,0 +1,90 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo;
import org.wso2.carbon.apimgt.api.model.APIRevisionDeployment;
import java.io.Serializable;
import java.util.List;
public class APIRevision implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String apiUUID;
private String revisionUUID;
private String description;
private String createdBy;
private String createdTime;
private List<APIRevisionDeployment> apiRevisionDeploymentList;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getApiUUID() {
return apiUUID;
}
public void setApiUUID(String apiUUID) {
this.apiUUID = apiUUID;
}
public String getRevisionUUID() {
return revisionUUID;
}
public void setRevisionUUID(String revisionUUID) {
this.revisionUUID = revisionUUID;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public String getCreatedTime() {
return createdTime;
}
public void setCreatedTime(String createdTime) {
this.createdTime = createdTime;
}
public List<APIRevisionDeployment> getApiRevisionDeploymentList() {
return apiRevisionDeploymentList;
}
public void setApiRevisionDeploymentList(List<APIRevisionDeployment> apiRevisionDeploymentList) {
this.apiRevisionDeploymentList = apiRevisionDeploymentList;
}
}

@ -0,0 +1,79 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo;
import java.io.Serializable;
public class APIRevisionDeployment implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String revisionUUID;
private String deployment;
private String vhost;
private boolean isDisplayOnDevportal;
private String deployedTime;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRevisionUUID() {
return revisionUUID;
}
public void setRevisionUUID(String revisionUUID) {
this.revisionUUID = revisionUUID;
}
public String getDeployment() {
return deployment;
}
public void setDeployment(String deployment) {
this.deployment = deployment;
}
public String getVhost() {
return vhost;
}
public void setVhost(String vhost) {
this.vhost = vhost;
}
public boolean isDisplayOnDevportal() {
return isDisplayOnDevportal;
}
public void setDisplayOnDevportal(boolean displayOnDevportal) {
isDisplayOnDevportal = displayOnDevportal;
}
public String getDeployedTime() {
return deployedTime;
}
public void setDeployedTime(String deployedTime) {
this.deployedTime = deployedTime;
}
}

@ -1,12 +1,12 @@
/*
* Copyright (c) 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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
@ -15,7 +15,6 @@
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo;
/**

@ -1,12 +1,12 @@
/*
* Copyright (c) 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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

@ -0,0 +1,82 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo;
import java.util.List;
/**
* API CORS Configuration
*/
public class CORSConfiguration {
private boolean corsConfigurationEnabled;
private List<String> accessControlAllowOrigins;
private boolean accessControlAllowCredentials;
private List<String> accessControlAllowHeaders;
private List<String> accessControlAllowMethods;
public CORSConfiguration(boolean corsConfigurationEnabled, List<String> accessControlAllowOrigins,
boolean accessControlAllowCredentials,
List<String> accessControlAllowHeaders, List<String> accessControlAllowMethods) {
this.corsConfigurationEnabled = corsConfigurationEnabled;
this.accessControlAllowOrigins = accessControlAllowOrigins;
this.accessControlAllowCredentials = accessControlAllowCredentials;
this.accessControlAllowHeaders = accessControlAllowHeaders;
this.accessControlAllowMethods = accessControlAllowMethods;
}
public boolean isCorsConfigurationEnabled() {
return corsConfigurationEnabled;
}
public void setCorsConfigurationEnabled(boolean corsConfigurationEnabled) {
this.corsConfigurationEnabled = corsConfigurationEnabled;
}
public List<String> getAccessControlAllowOrigins() {
return accessControlAllowOrigins;
}
public void setAccessControlAllowOrigins(List<String> accessControlAllowOrigins) {
this.accessControlAllowOrigins = accessControlAllowOrigins;
}
public boolean isAccessControlAllowCredentials() {
return accessControlAllowCredentials;
}
public void setAccessControlAllowCredentials(boolean accessControlAllowCredentials) {
this.accessControlAllowCredentials = accessControlAllowCredentials;
}
public List<String> getAccessControlAllowHeaders() {
return accessControlAllowHeaders;
}
public void setAccessControlAllowHeaders(List<String> accessControlAllowHeaders) {
this.accessControlAllowHeaders = accessControlAllowHeaders;
}
public List<String> getAccessControlAllowMethods() {
return accessControlAllowMethods;
}
public void setAccessControlAllowMethods(List<String> accessControlAllowMethods) {
this.accessControlAllowMethods = accessControlAllowMethods;
}
}

@ -0,0 +1,192 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo;
import java.util.Date;
public class Documentation {
private static final long serialVersionUID = 1L;
private String id;
private String documentId;
private DocumentationType type;
private String name;
private String summary;
private DocumentSourceType sourceType;
private String sourceUrl;
private DocumentVisibility visibility;
private Date lastUpdated;
private String filePath;
private Date createdDate;
private String otherTypeName;
public String getOtherTypeName() {
return this.otherTypeName;
}
public void setOtherTypeName(String otherTypeName) {
this.otherTypeName = otherTypeName;
}
public String getFilePath() {
return this.filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public String getSourceUrl() {
return this.sourceUrl;
}
public void setSourceUrl(String sourceUrl) {
this.sourceUrl = sourceUrl;
}
public Documentation(DocumentationType type, String name) {
this.type = type;
this.name = name;
}
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
Documentation that = (Documentation)o;
return this.name.equals(that.name) && this.type == that.type;
} else {
return false;
}
}
public DocumentationType getType() {
return this.type;
}
public String getName() {
return this.name;
}
public String getSummary() {
return this.summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public DocumentVisibility getVisibility() {
return this.visibility;
}
public void setVisibility(DocumentVisibility visibility) {
this.visibility = visibility;
}
public DocumentSourceType getSourceType() {
return this.sourceType;
}
public void setSourceType(DocumentSourceType sourceType) {
this.sourceType = sourceType;
}
public int hashCode() {
int result = this.type.hashCode();
result = 31 * result + this.name.hashCode();
return result;
}
public Date getLastUpdated() {
return this.lastUpdated;
}
public void setLastUpdated(Date lastUpdated) {
this.lastUpdated = lastUpdated;
}
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
public String getDocumentId() {
return documentId;
}
public void setDocumentId(String documentId) {
this.documentId = documentId;
}
public Date getCreatedDate() {
return this.createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
public static enum DocumentVisibility {
OWNER_ONLY("owner_only"),
PRIVATE("private"),
API_LEVEL("api_level");
private String visibility;
private DocumentVisibility(String visibility) {
this.visibility = visibility;
}
}
public static enum DocumentSourceType {
INLINE("In line"),
MARKDOWN("Markdown"),
URL("URL"),
FILE("File");
private String type;
private DocumentSourceType(String type) {
this.type = type;
}
}
public static enum DocumentationType {
HOWTO("How To"),
SAMPLES("Samples"),
PUBLIC_FORUM("Public Forum"),
SUPPORT_FORUM("Support Forum"),
API_MESSAGE_FORMAT("API Message Format"),
SWAGGER_DOC("Swagger API Definition"),
OTHER("Other");
private String type;
private DocumentationType(String type) {
this.type = type;
}
public String getType() {
return type;
}
}
}

@ -0,0 +1,54 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo;
public class Mediation {
private String uuid;
private String name;
private String type;
private String config;
private boolean isGlobal;
public Mediation(){}
public void setUuid(String id){
this.uuid=id;
}
public String getUuid(){return uuid;}
public void setName(String name){this.name=name;}
public String getName(){return name;}
public void setType(String mType){this.type=mType;}
public String getType(){return type;}
public void setConfig(String mConfig){this.config=mConfig;}
public String getConfig(){return config;}
public boolean isGlobal() {
return isGlobal;
}
public void setGlobal(boolean isGlobal) {
this.isGlobal = isGlobal;
}
}

@ -1,12 +1,12 @@
/*
* Copyright (c) 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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

@ -0,0 +1,100 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo;
import java.io.Serializable;
import java.util.Objects;
public class Scope implements Serializable{
private static final long serialVersionUID = 1L;
String key;
String name;
String roles;
String description;
String id;
int usageCount;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRoles() {
return roles;
}
public void setRoles(String roles) {
this.roles = roles;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getUsageCount() {
return usageCount;
}
public void setUsageCount(int usageCount) {
this.usageCount = usageCount;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Scope scope = (Scope) o;
if (id != null ? !id.equals(scope.id) : scope.id != null) return false;
if (!key.equals(scope.key)) return false;
if (!name.equals(scope.name)) return false;
if (roles != null ? !roles.equals(scope.roles) : scope.roles != null) return false;
return description != null ? description.equals(scope.description) : scope.description == null;
}
@Override
public int hashCode() {
return Objects.hash(key, name, roles, description, id);
}
}

@ -0,0 +1,440 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo;
import org.json.simple.JSONValue;
import org.wso2.carbon.apimgt.api.dto.ConditionGroupDTO;
import org.wso2.carbon.apimgt.api.model.APIProductIdentifier;
import org.wso2.carbon.apimgt.api.model.Scope;
import org.wso2.carbon.apimgt.api.model.policy.PolicyConstants;
import java.io.Serializable;
import java.util.*;
public class URITemplate implements Serializable{
private static final long serialVersionUID = 1L;
private String uriTemplate;
private String resourceURI;
private String resourceSandboxURI;
private String httpVerb;
private String authType;
private LinkedHashSet<String> httpVerbs = new LinkedHashSet<String>();
private List<String> authTypes = new ArrayList<String>();
private List<String> throttlingConditions = new ArrayList<String>();
private String applicableLevel;
private String throttlingTier;
private List<String> throttlingTiers = new ArrayList<String>();
private org.wso2.carbon.apimgt.api.model.Scope scope;
private String mediationScript;
private List<org.wso2.carbon.apimgt.api.model.Scope> scopes = new ArrayList<org.wso2.carbon.apimgt.api.model.Scope>();
private Map<String, String> mediationScripts = new HashMap<String, String>();
private ConditionGroupDTO[] conditionGroups;
private int id;
private Set<APIProductIdentifier> usedByProducts = new HashSet<>();
private String amznResourceName;
private int amznResourceTimeout;
public ConditionGroupDTO[] getConditionGroups() {
return conditionGroups;
}
public void setConditionGroups(ConditionGroupDTO[] conditionGroups) {
this.conditionGroups = conditionGroups;
}
public String getMediationScript() {
return mediationScript;
}
public List<String> getThrottlingConditions() {
return throttlingConditions;
}
public void setThrottlingConditions(List<String> throttlingConditions) {
this.throttlingConditions = throttlingConditions;
}
public void setMediationScript(String mediationScript) {
this.mediationScript = mediationScript;
}
/**
* Set mediation script for a given http method
* @param method http method name
* @param mediationScript mediation script content
*/
public void setMediationScripts(String method, String mediationScript){
if (mediationScript != null && !mediationScript.trim().equals("") && !mediationScript.trim().equals("null")){
mediationScripts.put(method, mediationScript);
}
}
/**
* Generating the script by aggregating scripts of each http method to form a single script in to be
* used when generating synapse configuration file.
*
* @return aggregated script in the following format,
* if (http-method = 'GET'){
* //script for GET
* }
* ....
* ....
* if (http-method = 'POST'){
* //script for POST
* }
*/
public String getAggregatedMediationScript(){
if (mediationScripts.isEmpty()){
return "null";
}else if (mediationScripts.size() == 1 && httpVerbs.size() == 1){
return mediationScript;
}else{
StringBuilder aggregatedScript = new StringBuilder();
for (Map.Entry<String, String> entry : mediationScripts.entrySet()){
String httpMethod = entry.getKey();
String mediationScript = entry.getValue();
aggregatedScript.append("if (mc.getProperty('REST_METHOD') == '").append(httpMethod).append("'){");
aggregatedScript.append(mediationScript);
aggregatedScript.append("}");
}
return aggregatedScript.toString();
}
}
public String getThrottlingTier() {
return throttlingTier;
}
public void setThrottlingTier(String throttlingTier) {
this.throttlingTier = throttlingTier;
}
public List<String> getThrottlingTiers(){
return throttlingTiers;
}
public void setThrottlingTiers(List<String> throttlingTiers) {
this.throttlingTiers = throttlingTiers;
}
public String getHTTPVerb() {
return httpVerb;
}
public void setHTTPVerb(String httpVerb) {
this.httpVerb = httpVerb;
}
public String getAuthType() {
return authType;
}
public void setAuthType(String authType) {
this.authType = authType;
}
public String getResourceURI() {
return resourceURI;
}
public void setResourceURI(String resourceURI) {
this.resourceURI = resourceURI;
}
public boolean isResourceURIExist(){
return this.resourceURI != null;
}
public String getResourceSandboxURI() {
return resourceSandboxURI;
}
public void setResourceSandboxURI(String resourceSandboxURI) {
this.resourceSandboxURI = resourceSandboxURI;
}
public boolean isResourceSandboxURIExist(){
return this.resourceSandboxURI != null;
}
public String getUriTemplate() {
return uriTemplate;
}
public void setUriTemplate(String template) {
this.uriTemplate = template;
}
public void setHttpVerbs(String httpVerb) {
httpVerbs.add(httpVerb);
}
public LinkedHashSet<String> getHttpVerbs() {
return httpVerbs;
}
public void setAuthTypes(String authType) {
authTypes.add(authType);
}
public String getAuthTypes() {
return authType;
}
public String getMethodsAsString() {
StringBuilder stringBuilder = new StringBuilder();
for (String method : httpVerbs) {
stringBuilder.append(method).append(" ");
}
return stringBuilder.toString().trim();
}
public String getAuthTypeAsString() {
StringBuilder stringBuilder = new StringBuilder();
for (String authType : authTypes) {
stringBuilder.append(authType).append(" ");
}
return stringBuilder.toString().trim();
}
public String getThrottlingConditionsAsString() {
StringBuilder stringBuilder = new StringBuilder();
for (String authType : throttlingConditions) {
stringBuilder.append(authType).append(" ");
}
return stringBuilder.toString().trim();
}
public void setThrottlingTiers(String tier) {
throttlingTiers.add(tier);
}
public String getThrottlingTiersAsString() {
StringBuilder stringBuilder = new StringBuilder();
for (String tier : throttlingTiers) {
if (tier.contains(PolicyConstants.THROTTLING_TIER_CONTENT_AWARE_SEPERATOR)) {
stringBuilder.append(tier.substring(0,
tier.indexOf(PolicyConstants.THROTTLING_TIER_CONTENT_AWARE_SEPERATOR)).trim()).append(" ");
} else {
stringBuilder.append(tier.trim()).append(" ");
}
}
return stringBuilder.toString().trim();
}
public boolean checkContentAwareFromThrottlingTiers() {
// use the content aware property appended to throttling tiers
if (!throttlingTiers.isEmpty()) {
String throttlingTierWithContentAware = throttlingTiers.get(0);
if (throttlingTierWithContentAware != null &&
throttlingTierWithContentAware.contains(PolicyConstants.THROTTLING_TIER_CONTENT_AWARE_SEPERATOR)) {
String[] splitThrottlingTiers =
throttlingTierWithContentAware.split(PolicyConstants.THROTTLING_TIER_CONTENT_AWARE_SEPERATOR);
return Boolean.valueOf(splitThrottlingTiers[splitThrottlingTiers.length - 1]);
}
}
return false;
}
public org.wso2.carbon.apimgt.api.model.Scope getScope() {
return scope;
}
public List<org.wso2.carbon.apimgt.api.model.Scope> getScopes() {
return scopes;
}
public void setScope(org.wso2.carbon.apimgt.api.model.Scope scope) {
this.scope = scope;
}
public void setScopes(org.wso2.carbon.apimgt.api.model.Scope scope){
this.scopes.add(scope);
}
public String getResourceMap(){
Map verbs = new LinkedHashMap();
int i = 0;
for (String method : httpVerbs) {
Map verb = new LinkedHashMap();
verb.put("auth_type",authTypes.get(i));
verb.put("throttling_tier",throttlingTiers.get(i));
//Following parameter is not required as it not need to reflect UI level. If need please enable it.
// /verb.put("throttling_conditions", throttlingConditions.get(i));
try{
org.wso2.carbon.apimgt.api.model.Scope tmpScope = scopes.get(i);
if(tmpScope != null){
verb.put("scope",tmpScope.getKey());
}
}catch(IndexOutOfBoundsException e){
//todo need to rewrite to prevent this type of exceptions
}
verbs.put(method,verb);
i++;
}
//todo this is a hack to make key validation service stub from braking need to rewrite.
return JSONValue.toJSONString(verbs);
}
public String getApplicableLevel() {
return applicableLevel;
}
public void setApplicableLevel(String applicableLevel) {
this.applicableLevel = applicableLevel;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
URITemplate that = (URITemplate) o;
if (!uriTemplate.equals(that.uriTemplate)) {
return false;
}
if (resourceURI != null ? !resourceURI.equals(that.resourceURI) : that.resourceURI != null) {
return false;
}
if (resourceSandboxURI != null ? !resourceSandboxURI.equals(that.resourceSandboxURI) : that
.resourceSandboxURI != null) {
return false;
}
if (!httpVerb.equals(that.httpVerb)) {
return false;
}
if (!authType.equals(that.authType)) {
return false;
}
if (!httpVerbs.equals(that.httpVerbs)) {
return false;
}
if (!authTypes.equals(that.authTypes)) {
return false;
}
if (throttlingConditions != null ? !throttlingConditions.equals(that.throttlingConditions) : that
.throttlingConditions != null) {
return false;
}
if (applicableLevel != null ? !applicableLevel.equals(that.applicableLevel) : that.applicableLevel != null) {
return false;
}
if (!throttlingTier.equals(that.throttlingTier)) {
return false;
}
if (!throttlingTiers.equals(that.throttlingTiers)) {
return false;
}
if (scope != null ? !scope.equals(that.scope) : that.scope != null) {
return false;
}
if (mediationScript != null ? !mediationScript.equals(that.mediationScript) : that.mediationScript != null) {
return false;
}
if (scopes != null ? !scopes.equals(that.scopes) : that.scopes != null) {
return false;
}
if (mediationScripts != null ? !mediationScripts.equals(that.mediationScripts) : that.mediationScripts !=
null) {
return false;
}
// Probably incorrect - comparing Object[] arrays with Arrays.equals
return Arrays.equals(conditionGroups, that.conditionGroups);
}
@Override
public int hashCode() {
int result = uriTemplate.hashCode();
result = 31 * result + (resourceURI != null ? resourceURI.hashCode() : 0);
result = 31 * result + (resourceSandboxURI != null ? resourceSandboxURI.hashCode() : 0);
result = 31 * result + (httpVerb != null ? httpVerb.hashCode() : 0);
result = 31 * result + (authType != null ? authType.hashCode() : 0);
result = 31 * result + (httpVerbs != null ? httpVerbs.hashCode() : 0);
result = 31 * result + (authTypes != null ? authTypes.hashCode() : 0);
result = 31 * result + (throttlingConditions != null ? throttlingConditions.hashCode() : 0);
result = 31 * result + (applicableLevel != null ? applicableLevel.hashCode() : 0);
result = 31 * result + (throttlingTier != null ? throttlingTier.hashCode() : 0);
result = 31 * result + (throttlingTiers != null ? throttlingTiers.hashCode() : 0);
result = 31 * result + (scope != null ? scope.hashCode() : 0);
result = 31 * result + (mediationScript != null ? mediationScript.hashCode() : 0);
result = 31 * result + (scopes != null ? scopes.hashCode() : 0);
result = 31 * result + (mediationScripts != null ? mediationScripts.hashCode() : 0);
result = 31 * result + Arrays.hashCode(conditionGroups);
return result;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public List<org.wso2.carbon.apimgt.api.model.Scope> retrieveAllScopes() {
return this.scopes;
}
public void addAllScopes(List<Scope> scopes) {
this.scopes = scopes;
}
public Set<APIProductIdentifier> retrieveUsedByProducts() {
return usedByProducts;
}
public void addUsedByProduct(APIProductIdentifier usedByProduct) {
usedByProducts.add(usedByProduct);
}
public void setAmznResourceName(String amznResourceName) {
this.amznResourceName = amznResourceName;
}
public String getAmznResourceName() {
return amznResourceName;
}
public void setAmznResourceTimeout(int amznResourceTimeout) {
this.amznResourceTimeout = amznResourceTimeout;
}
public int getAmznResourceTimeout() {
return amznResourceTimeout;
}
}

@ -21,7 +21,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -21,7 +21,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,26 +23,29 @@ import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServi
import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServicesImpl;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.constants.Constants;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIApplicationKey;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.APIInfo;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Scope;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Mediation;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Documentation;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.APIRevision;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.APIRevisionDeployment;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.CORSConfiguration;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.AccessTokenInfo;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.APIServicesException;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.BadRequestException;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.exceptions.UnexpectedResponseException;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.APIInfo;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.config.WebappPublisherConfig;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.dto.ApiScope;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.dto.ApiUriTemplate;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.exception.APIManagerPublisherException;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.apimgt.api.model.Documentation;
import org.wso2.carbon.apimgt.api.model.DocumentationType;
import org.json.JSONArray;
import org.json.JSONObject;
import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.api.APIProvider;
import org.wso2.carbon.apimgt.api.model.APIIdentifier;
import org.wso2.carbon.apimgt.api.model.APIRevision;
import org.wso2.carbon.apimgt.api.model.APIRevisionDeployment;
import org.wso2.carbon.apimgt.api.model.CORSConfiguration;
import org.wso2.carbon.apimgt.api.model.Mediation;
import org.wso2.carbon.apimgt.api.model.Scope;
import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.apimgt.impl.APIManagerFactory;
import org.wso2.carbon.apimgt.impl.utils.APIUtil;
@ -167,6 +170,7 @@ public class APIPublisherServiceImpl implements APIPublisherService {
break;
}
}
String apiUuid = apiIdentifier.getUUID();
if (!apiFound) {
// add new scopes as shared scopes
for (ApiScope apiScope : apiConfig.getScopes()) {
@ -182,9 +186,10 @@ public class APIPublisherServiceImpl implements APIPublisherService {
}
APIInfo api = getAPI(apiConfig, true);
JSONObject createdAPI = publisherRESTAPIServices.addAPI(apiApplicationKey, accessTokenInfo, api);
apiUuid = createdAPI.getString("id");
if (apiConfig.getEndpointType() != null && "WS".equals(apiConfig.getEndpointType())) {
publisherRESTAPIServices.saveAsyncApiDefinition(apiApplicationKey, accessTokenInfo,
createdAPI.getString("id"), apiConfig.getAsyncApiDefinition());
apiUuid, apiConfig.getAsyncApiDefinition());
}
if (CREATED_STATUS.equals(createdAPI.getString("lifeCycleStatus"))) {
// if endpoint type "dynamic" and then add in sequence
@ -195,13 +200,13 @@ public class APIPublisherServiceImpl implements APIPublisherService {
mediation.setType("in");
mediation.setGlobal(false);
publisherRESTAPIServices.addApiSpecificMediationPolicy(apiApplicationKey,
accessTokenInfo, createdAPI.getString("id"), mediation);
accessTokenInfo, apiUuid, mediation);
}
publisherRESTAPIServices.changeLifeCycleStatus(apiApplicationKey, accessTokenInfo,
createdAPI.getString("id"), PUBLISH_ACTION);
apiUuid, PUBLISH_ACTION);
APIRevision apiRevision = new APIRevision();
apiRevision.setApiUUID(createdAPI.getString("id"));
apiRevision.setApiUUID(apiUuid);
apiRevision.setDescription("Initial Revision");
String apiRevisionId = publisherRESTAPIServices.addAPIRevision(apiApplicationKey,
accessTokenInfo, apiRevision).getString("id");
@ -214,7 +219,7 @@ public class APIPublisherServiceImpl implements APIPublisherService {
List<APIRevisionDeployment> apiRevisionDeploymentList = new ArrayList<>();
apiRevisionDeploymentList.add(apiRevisionDeployment);
publisherRESTAPIServices.deployAPIRevision(apiApplicationKey, accessTokenInfo,
createdAPI.getString("id"), apiRevisionId, apiRevisionDeploymentList);
apiUuid, apiRevisionId, apiRevisionDeploymentList);
}
} else {
if (WebappPublisherConfig.getInstance().isEnabledUpdateApi()) {
@ -257,7 +262,7 @@ public class APIPublisherServiceImpl implements APIPublisherService {
// Get existing API
JSONObject existingAPI = publisherRESTAPIServices.getApi(apiApplicationKey, accessTokenInfo,
apiIdentifier);
apiUuid);
if (scopesToMoveAsSharedScopes.size() > 0) {
// update API to remove local scopes
APIInfo api = getAPI(apiConfig, false);
@ -274,15 +279,15 @@ public class APIPublisherServiceImpl implements APIPublisherService {
}
}
existingAPI = publisherRESTAPIServices.getApi(apiApplicationKey, accessTokenInfo, apiIdentifier);
existingAPI = publisherRESTAPIServices.getApi(apiApplicationKey, accessTokenInfo, apiUuid);
APIInfo api = getAPI(apiConfig, true);
api.setLastUpdatedTime(existingAPI.getString("lifeCycleStatus"));
api.setId(existingAPI.getString("id"));
api.setId(apiUuid);
publisherRESTAPIServices.updateApi(apiApplicationKey, accessTokenInfo, api);
if (apiConfig.getEndpointType() != null && "WS".equals(apiConfig.getEndpointType())) {
publisherRESTAPIServices.saveAsyncApiDefinition(apiApplicationKey, accessTokenInfo,
existingAPI.getString("id"), apiConfig.getAsyncApiDefinition());
apiUuid, apiConfig.getAsyncApiDefinition());
}
// if endpoint type "dynamic" and then add /update in sequence
@ -293,48 +298,55 @@ public class APIPublisherServiceImpl implements APIPublisherService {
mediation.setType("in");
mediation.setGlobal(false);
List<Mediation> mediationList = (List) publisherRESTAPIServices
JSONArray mediationList = (JSONArray) publisherRESTAPIServices
.getAllApiSpecificMediationPolicies(apiApplicationKey, accessTokenInfo,
apiIdentifier).get("list");
apiUuid).get("list");
boolean isMediationPolicyFound = false;
for (Mediation m : mediationList) {
if (apiConfig.getInSequenceName().equals(m.getName())) {
m.setConfig(apiConfig.getInSequenceConfig());
publisherRESTAPIServices.
updateApiSpecificMediationPolicyContent(apiApplicationKey,
accessTokenInfo, existingAPI.getString("id"), m);
for (int i = 0; i < mediationList.length(); i++) {
JSONObject mediationObj = mediationList.getJSONObject(i);
if (apiConfig.getInSequenceName().equals(mediationObj.getString("name"))) {
mediation.setUuid(mediationObj.getString("id"));
publisherRESTAPIServices.deleteApiSpecificMediationPolicy(apiApplicationKey,
accessTokenInfo, apiUuid, mediation);
publisherRESTAPIServices.addApiSpecificMediationPolicy(apiApplicationKey,
accessTokenInfo, apiUuid, mediation);
isMediationPolicyFound = true;
break;
}
}
if (!isMediationPolicyFound) {
publisherRESTAPIServices.addApiSpecificMediationPolicy(apiApplicationKey,
accessTokenInfo, existingAPI.getString("id"), mediation);
accessTokenInfo, apiUuid, mediation);
}
}
// This will retrieve the deployed revision
JSONArray revisionDeploymentList = (JSONArray) publisherRESTAPIServices.getAPIRevisions(apiApplicationKey,
accessTokenInfo, existingAPI.getString("id"), true).get("list");
// This will retrieve the un deployed revision list
JSONArray undeployedRevisionList = (JSONArray) publisherRESTAPIServices.getAPIRevisions(apiApplicationKey,
accessTokenInfo, existingAPI.getString("id"), false).get("list");
int apiRevisionCount = (int) publisherRESTAPIServices.getAPIRevisions(apiApplicationKey,
accessTokenInfo, existingAPI.getString("id"), null).get("count");
accessTokenInfo, apiUuid, null).get("count");
if (apiRevisionCount >= 5) {
JSONObject latestRevisionDeployment = revisionDeploymentList.getJSONObject(0);
JSONObject earliestUndeployRevision = undeployedRevisionList.getJSONObject(0);
publisherRESTAPIServices.undeployAPIRevisionDeployment(apiApplicationKey,
accessTokenInfo, latestRevisionDeployment, existingAPI.getString("id"));
publisherRESTAPIServices.deleteAPIRevision(apiApplicationKey, accessTokenInfo,
earliestUndeployRevision, existingAPI.getString("id"));
// This will retrieve the deployed revision
JSONArray revisionDeploymentList = (JSONArray) publisherRESTAPIServices.getAPIRevisions(
apiApplicationKey, accessTokenInfo, apiUuid,
true).get("list");
if (revisionDeploymentList.length() > 0) {
JSONObject latestRevisionDeployment = revisionDeploymentList.getJSONObject(0);
publisherRESTAPIServices.undeployAPIRevisionDeployment(apiApplicationKey,
accessTokenInfo, latestRevisionDeployment, apiUuid);
}
// This will retrieve the un deployed revision list
JSONArray undeployedRevisionList = (JSONArray) publisherRESTAPIServices.getAPIRevisions(
apiApplicationKey, accessTokenInfo, apiUuid,
false).get("list");
if (undeployedRevisionList.length() > 0) {
JSONObject earliestUndeployRevision = undeployedRevisionList.getJSONObject(0);
publisherRESTAPIServices.deleteAPIRevision(apiApplicationKey, accessTokenInfo,
earliestUndeployRevision, apiUuid);
}
}
// create new revision
APIRevision apiRevision = new APIRevision();
apiRevision.setApiUUID(existingAPI.getString("id"));
apiRevision.setApiUUID(apiUuid);
apiRevision.setDescription("Updated Revision");
String apiRevisionId = publisherRESTAPIServices.addAPIRevision(apiApplicationKey,
accessTokenInfo, apiRevision).getString("id");
@ -348,17 +360,15 @@ public class APIPublisherServiceImpl implements APIPublisherService {
apiRevisionDeploymentList.add(apiRevisionDeployment);
publisherRESTAPIServices.deployAPIRevision(apiApplicationKey, accessTokenInfo,
existingAPI.getString("id"), apiRevisionId, apiRevisionDeploymentList);
apiUuid, apiRevisionId, apiRevisionDeploymentList);
if (CREATED_STATUS.equals(existingAPI.getString("lifeCycleStatus"))) {
publisherRESTAPIServices.changeLifeCycleStatus(apiApplicationKey,accessTokenInfo,
existingAPI.getString("id"), PUBLISH_ACTION);
apiUuid, PUBLISH_ACTION);
}
}
}
if (apiConfig.getApiDocumentationSourceFile() != null) {
APIInfo api = getAPI(apiConfig, true);
if (apiUuid != null && apiConfig.getApiDocumentationSourceFile() != null) {
String fileName =
CarbonUtils.getCarbonHome() + File.separator + "repository" +
File.separator + "resources" + File.separator + "api-docs" + File.separator +
@ -376,7 +386,7 @@ public class APIPublisherServiceImpl implements APIPublisherService {
br.close();
String docContent = stringBuilder.toString();
Documentation apiDocumentation = new Documentation(DocumentationType.HOWTO, apiConfig.getApiDocumentationName());
Documentation apiDocumentation = new Documentation(Documentation.DocumentationType.HOWTO, apiConfig.getApiDocumentationName());
apiDocumentation.setVisibility(Documentation.DocumentVisibility.API_LEVEL);
apiDocumentation.setSourceType(Documentation.DocumentSourceType.MARKDOWN);
apiDocumentation.setCreatedDate(new Date());
@ -385,25 +395,27 @@ public class APIPublisherServiceImpl implements APIPublisherService {
apiDocumentation.setOtherTypeName(null);
JSONArray documentList = (JSONArray) publisherRESTAPIServices.getDocumentations(apiApplicationKey,
accessTokenInfo, api.getId()).get("list");
accessTokenInfo, apiUuid).get("list");
if (documentList.length() > 0) {
for (int i = 0; i < documentList.length(); i++) {
JSONObject existingDoc = documentList.getJSONObject(i);
if (existingDoc.getString("name").equals(apiConfig.getApiDocumentationName())
&& existingDoc.getString("type").equals(DocumentationType.HOWTO)) {
&& existingDoc.getString("type").equals(Documentation.DocumentationType.HOWTO.name())) {
publisherRESTAPIServices.deleteDocumentations(apiApplicationKey, accessTokenInfo,
api.getId(), existingDoc.getString("documentId"));
apiUuid, existingDoc.getString("documentId"));
}
}
} else {
log.info("There is no any existing api documentation.");
}
Documentation createdDoc = publisherRESTAPIServices.addDocumentation(apiApplicationKey, accessTokenInfo,
api.getId(), apiDocumentation);
publisherRESTAPIServices.addDocumentationContent(apiApplicationKey, accessTokenInfo, api,
createdDoc.getId(), docContent);
io.entgra.device.mgt.core.apimgt.extension.rest.api.dto.APIInfo.Documentation createdDoc = publisherRESTAPIServices.addDocumentation(apiApplicationKey, accessTokenInfo,
apiUuid, apiDocumentation);
publisherRESTAPIServices.addDocumentationContent(apiApplicationKey, accessTokenInfo, apiUuid,
createdDoc.getDocumentId(), docContent);
}
} catch (APIManagementException | IOException | APIServicesException |
BadRequestException | UnexpectedResponseException e) {
@ -572,45 +584,49 @@ public class APIPublisherServiceImpl implements APIPublisherService {
}
apiInfo.setPolicies(availableTiers);
if (config.getEndpointType() == null) {
List<JSONObject> operations = new ArrayList();
List<JSONObject> scopeSet = new ArrayList();
Iterator<ApiUriTemplate> iterator;
for (iterator = config.getUriTemplates().iterator(); iterator.hasNext(); ) {
ApiUriTemplate apiUriTemplate = iterator.next();
JSONObject operation = new JSONObject();
operation.put("target", apiUriTemplate.getUriTemplate());
operation.put("verb", apiUriTemplate.getHttpVerb());
operation.put("authType", apiUriTemplate.getAuthType());
operation.put("throttlingPolicy", UNLIMITED_TIER);
if (includeScopes) {
if (apiUriTemplate.getScope() != null) {
String scopeString = "{\n" +
" \"scope\": {\n" +
" \"id\": null,\n" +
" \"name\": \"" + apiUriTemplate.getScope().getKey() + "\",\n" +
" \"displayName\": \"" + apiUriTemplate.getScope().getName() + "\",\n" +
" \"description\": \"" + apiUriTemplate.getScope().getDescription() + "\",\n" +
" \"bindings\": [\n" +
" \"" + apiUriTemplate.getScope().getRoles() + "\"\n" +
" ],\n" +
" \"usageCount\": null\n" +
" },\n" +
" \"shared\": true\n" +
" }";
JSONObject scope = new JSONObject(scopeString);
scopeSet.add(scope);
Set<String> scopes = new HashSet<>();
scopes.add(apiUriTemplate.getScope().getKey());
operation.put("scopes", scopes);
}
if (config.getEndpointType() != null && "WS".equals(config.getEndpointType())) {
apiInfo.setAsyncApiDefinition(config.getAsyncApiDefinition());
}
//set operations and scopes
List<JSONObject> operations = new ArrayList();
List<JSONObject> scopeSet = new ArrayList();
Iterator<ApiUriTemplate> iterator;
for (iterator = config.getUriTemplates().iterator(); iterator.hasNext(); ) {
ApiUriTemplate apiUriTemplate = iterator.next();
JSONObject operation = new JSONObject();
operation.put("target", apiUriTemplate.getUriTemplate());
operation.put("verb", apiUriTemplate.getHttpVerb());
operation.put("authType", apiUriTemplate.getAuthType());
operation.put("throttlingPolicy", UNLIMITED_TIER);
operation.put("uriMapping", apiUriTemplate.getUriMapping());
if (includeScopes) {
if (apiUriTemplate.getScope() != null) {
String scopeString = "{\n" +
" \"scope\": {\n" +
" \"id\": null,\n" +
" \"name\": \"" + apiUriTemplate.getScope().getKey() + "\",\n" +
" \"displayName\": \"" + apiUriTemplate.getScope().getName() + "\",\n" +
" \"description\": \"" + apiUriTemplate.getScope().getDescription() + "\",\n" +
" \"bindings\": [\n" +
" \"" + apiUriTemplate.getScope().getRoles() + "\"\n" +
" ],\n" +
" \"usageCount\": null\n" +
" },\n" +
" \"shared\": true\n" +
" }";
JSONObject scope = new JSONObject(scopeString);
scopeSet.add(scope);
Set<String> scopes = new HashSet<>();
scopes.add(apiUriTemplate.getScope().getKey());
operation.put("scopes", scopes);
}
operations.add(operation);
}
apiInfo.setScopes(scopeSet);
apiInfo.setOperations(operations);
operations.add(operation);
}
apiInfo.setScopes(scopeSet);
apiInfo.setOperations(operations);
if (config.isSharedWithAllTenants()) {
apiInfo.setSubscriptionAvailability(SUBSCRIPTION_TO_ALL_TENANTS);
@ -640,7 +656,7 @@ public class APIPublisherServiceImpl implements APIPublisherService {
if (config.getEndpointType() != null && "dynamic".equals(config.getEndpointType())) {
endpointConfig = "{\n" +
" \"endpoint_type\": \"http\",\n" +
" \"endpoint_type\": \"default\",\n" +
" \"sandbox_endpoints\": {\n" +
" \"url\": \" default \"\n" +
" },\n" +
@ -649,8 +665,7 @@ public class APIPublisherServiceImpl implements APIPublisherService {
" }\n" +
" }";
endPointConfig = new JSONObject(endpointConfig);
//TODO: Will be used in dynamic endpoints
// apiInfo.setInSequence(config.getInSequenceName());
apiInfo.setInSequence(config.getInSequenceName());
}
// if ws endpoint
@ -702,42 +717,5 @@ public class APIPublisherServiceImpl implements APIPublisherService {
apiInfo.setServiceInfo(null);
return apiInfo;
//TODO: Will be used in WS or dynamic endpoints
// if (config.getEndpointType() != null && "WS".equals(config.getEndpointType())) {
// api.setAsyncApiDefinition(config.getAsyncApiDefinition());
// AsyncApiParser asyncApiParser = new AsyncApiParser();
// try {
// api.setUriTemplates(asyncApiParser.getURITemplates(config.getAsyncApiDefinition(), true));
// } catch (APIManagementException e) {
//
// }
// api.setWsUriMapping(asyncApiParser.buildWSUriMapping(config.getAsyncApiDefinition()));
// } else {
// api.setSwaggerDefinition(APIPublisherUtil.getSwaggerDefinition(config));
//
// Set<URITemplate> uriTemplates = new HashSet<>();
// Iterator<ApiUriTemplate> iterator;
// for (iterator = config.getUriTemplates().iterator(); iterator.hasNext(); ) {
// ApiUriTemplate apiUriTemplate = iterator.next();
// URITemplate uriTemplate = new URITemplate();
// uriTemplate.setAuthType(apiUriTemplate.getAuthType());
// uriTemplate.setHTTPVerb(apiUriTemplate.getHttpVerb());
// uriTemplate.setResourceURI(apiUriTemplate.getResourceURI());
// uriTemplate.setUriTemplate(apiUriTemplate.getUriTemplate());
// if (includeScopes) {
// Scope scope = new Scope();
// if (apiUriTemplate.getScope() != null) {
// scope.setName(apiUriTemplate.getScope().getName());
// scope.setDescription(apiUriTemplate.getScope().getDescription());
// scope.setKey(apiUriTemplate.getScope().getKey());
// scope.setRoles(apiUriTemplate.getScope().getRoles());
// uriTemplate.setScopes(scope);
// }
// }
// uriTemplates.add(uriTemplate);
// }
// api.setUriTemplates(uriTemplates);
// }
}
}

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>io.entgra.device.mgt.core.parent</artifactId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>application-mgt</artifactId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -0,0 +1,86 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.common;
public class DepConfig {
private String agentPackageName;
private String consumerKey;
private String consumerSecret;
private String accessToken;
private String accessSecret;
private String accessTokenExpiry;
private String vppToken;
public String getAgentPackageName() {
return agentPackageName;
}
public void setAgentPackageName(String agentPackageName) {
this.agentPackageName = agentPackageName;
}
public String getConsumerKey() {
return consumerKey;
}
public void setConsumerKey(String consumerKey) {
this.consumerKey = consumerKey;
}
public String getConsumerSecret() {
return consumerSecret;
}
public void setConsumerSecret(String consumerSecret) {
this.consumerSecret = consumerSecret;
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getVppToken() {
return vppToken;
}
public void setVppToken(String vppToken) {
this.vppToken = vppToken;
}
public String getAccessSecret() {
return accessSecret;
}
public void setAccessSecret(String accessSecret) {
this.accessSecret = accessSecret;
}
public String getAccessTokenExpiry() {
return accessTokenExpiry;
}
public void setAccessTokenExpiry(String accessTokenExpiry) {
this.accessTokenExpiry = accessTokenExpiry;
}
}

@ -0,0 +1,95 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.common.dto;
public class ItuneAppDTO {
int id;
String packageName;
String version;
String description;
String title;
String paymentMethod;
String iconURL;
String category;
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getIconURL() {
return iconURL;
}
public void setIconURL(String iconURL) {
this.iconURL = iconURL;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPaymentMethod() {
return paymentMethod;
}
public void setPaymentMethod(String paymentMethod) {
this.paymentMethod = paymentMethod;
}
}

@ -0,0 +1,37 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.common.dto;
public class ProxyResponse {
private int code;
private String data;
private String executorResponse;
public int getCode() { return code; }
public void setCode(int code) { this.code = code; }
public String getData() { return data; }
public void setData(String data) { this.data = data; }
public String getExecutorResponse() { return executorResponse; }
public void setExecutorResponse(String executorResponse) { this.executorResponse = executorResponse; }
}

@ -0,0 +1,67 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.common.dto;
public class VppAssetDTO extends VppItuneAssetDTO {
int id;
int appId;
int tenantId;
String createdTime;
String lastUpdatedTime;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAppId() {
return appId;
}
public void setAppId(int appId) {
this.appId = appId;
}
public int getTenantId() {
return tenantId;
}
public void setTenantId(int tenantId) {
this.tenantId = tenantId;
}
public String getCreatedTime() {
return createdTime;
}
public void setCreatedTime(String createdTime) {
this.createdTime = createdTime;
}
public String getLastUpdatedTime() {
return lastUpdatedTime;
}
public void setLastUpdatedTime(String lastUpdatedTime) {
this.lastUpdatedTime = lastUpdatedTime;
}
}

@ -0,0 +1,113 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.common.dto;
public class VppAssociationDTO {
int id;
String adamId;
String clientUserId;
String pricingParam;
String associationType;
int assetId;
int clientId;
int tenantId;
String createdTime;
String lastUpdatedTime;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAdamId() {
return adamId;
}
public void setAdamId(String adamId) {
this.adamId = adamId;
}
public String getClientUserId() {
return clientUserId;
}
public void setClientUserId(String clientUserId) {
this.clientUserId = clientUserId;
}
public String getPricingParam() {
return pricingParam;
}
public void setPricingParam(String pricingParam) {
this.pricingParam = pricingParam;
}
public String getAssociationType() {
return associationType;
}
public void setAssociationType(String associationType) {
this.associationType = associationType;
}
public int getAssetId() {
return assetId;
}
public void setAssetId(int assetId) {
this.assetId = assetId;
}
public int getClientId() {
return clientId;
}
public void setClientId(int clientId) {
this.clientId = clientId;
}
public int getTenantId() {
return tenantId;
}
public void setTenantId(int tenantId) {
this.tenantId = tenantId;
}
public String getCreatedTime() {
return createdTime;
}
public void setCreatedTime(String createdTime) {
this.createdTime = createdTime;
}
public String getLastUpdatedTime() {
return lastUpdatedTime;
}
public void setLastUpdatedTime(String lastUpdatedTime) {
this.lastUpdatedTime = lastUpdatedTime;
}
}

@ -0,0 +1,109 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the String LicenseString ); 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
* String AS ISString 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 io.entgra.device.mgt.core.application.mgt.common.dto;
import java.util.List;
public class VppItuneAssetDTO {
String adamId;
String assignedCount;
String availableCount;
String deviceAssignable;
String pricingParam;
String productType;
String retiredCount;
String revocable;
List<String> supportedPlatforms;
public List<String> getSupportedPlatforms() {
return supportedPlatforms;
}
public void setSupportedPlatforms(List<String> supportedPlatforms) {
this.supportedPlatforms = supportedPlatforms;
}
public String getAdamId() {
return adamId;
}
public void setAdamId(String adamId) {
this.adamId = adamId;
}
public String getAssignedCount() {
return assignedCount;
}
public void setAssignedCount(String assignedCount) {
this.assignedCount = assignedCount;
}
public String getAvailableCount() {
return availableCount;
}
public void setAvailableCount(String availableCount) {
this.availableCount = availableCount;
}
public String getDeviceAssignable() {
return deviceAssignable;
}
public void setDeviceAssignable(String deviceAssignable) {
this.deviceAssignable = deviceAssignable;
}
public String getPricingParam() {
return pricingParam;
}
public void setPricingParam(String pricingParam) {
this.pricingParam = pricingParam;
}
public String getProductType() {
return productType;
}
public void setProductType(String productType) {
this.productType = productType;
}
public String getRetiredCount() {
return retiredCount;
}
public void setRetiredCount(String retiredCount) {
this.retiredCount = retiredCount;
}
public String getRevocable() {
return revocable;
}
public void setRevocable(String revocable) {
this.revocable = revocable;
}
}

@ -0,0 +1,67 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.common.dto;
public class VppItuneUserDTO {
String clientUserId;
String inviteCode;
String status;
String email;
String managedId;
public String getClientUserId() {
return clientUserId;
}
public void setClientUserId(String clientUserId) {
this.clientUserId = clientUserId;
}
public String getInviteCode() {
return inviteCode;
}
public void setInviteCode(String inviteCode) {
this.inviteCode = inviteCode;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getManagedId() {
return managedId;
}
public void setManagedId(String managedId) {
this.managedId = managedId;
}
}

@ -0,0 +1,85 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.common.dto;
public class VppPaginationDTO {
int currentPageIndex;
int size;
String tokenExpirationDate;
int nextPageIndex;
int totalPages;
String uId;
String versionId;
public int getCurrentPageIndex() {
return currentPageIndex;
}
public void setCurrentPageIndex(int currentPageIndex) {
this.currentPageIndex = currentPageIndex;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public String getTokenExpirationDate() {
return tokenExpirationDate;
}
public void setTokenExpirationDate(String tokenExpirationDate) {
this.tokenExpirationDate = tokenExpirationDate;
}
public int getNextPageIndex() {
return nextPageIndex;
}
public void setNextPageIndex(int nextPageIndex) {
this.nextPageIndex = nextPageIndex;
}
public int getTotalPages() {
return totalPages;
}
public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
}
public String getuId() {
return uId;
}
public void setuId(String uId) {
this.uId = uId;
}
public String getVersionId() {
return versionId;
}
public void setVersionId(String versionId) {
this.versionId = versionId;
}
}

@ -0,0 +1,92 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.common.dto;
public class VppUserDTO extends VppItuneUserDTO {
int id;
String dmUsername;
int tenantId;
String createdTime;
String lastUpdatedTime;
String tmpPassword;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getDmUsername() {
return dmUsername;
}
public void setDmUsername(String dmUsername) {
this.dmUsername = dmUsername;
}
public int getTenantId() {
return tenantId;
}
public void setTenantId(int tenantId) {
this.tenantId = tenantId;
}
public String getCreatedTime() {
return createdTime;
}
public void setCreatedTime(String createdTime) {
this.createdTime = createdTime;
}
public String getLastUpdatedTime() {
return lastUpdatedTime;
}
public void setLastUpdatedTime(String lastUpdatedTime) {
this.lastUpdatedTime = lastUpdatedTime;
}
public String getTmpPassword() {
return tmpPassword;
}
public void setTmpPassword(String tmpPassword) {
this.tmpPassword = tmpPassword;
}
@Override
public String toString() {
return "VppUserDTO{" +
"id=" + id +
", dmUsername='" + dmUsername + '\'' +
", tenantId=" + tenantId +
", createdTime='" + createdTime + '\'' +
", lastUpdatedTime='" + lastUpdatedTime + '\'' +
", tmpPassword='" + tmpPassword + '\'' +
", clientUserId='" + clientUserId + '\'' +
", inviteCode='" + inviteCode + '\'' +
", status='" + status + '\'' +
", email='" + email + '\'' +
", managedId='" + managedId + '\'' +
'}';
}
}

@ -108,6 +108,12 @@ public class Application {
value = "if the app is favoured by the user")
private boolean isFavourite;
@ApiModelProperty(name = "isExternalAppStoreApp",
value = "Is the app coming from an external application store",
required = true,
example = "true or false")
private boolean isExternalAppStoreApp;
public String getPackageName() {
return packageName;
}
@ -194,4 +200,12 @@ public class Application {
public void setFavourite(boolean favourite) {
isFavourite = favourite;
}
public boolean isExternalAppStoreApp() {
return isExternalAppStoreApp;
}
public void setExternalAppStoreApp(boolean externalAppStoreApp) {
isExternalAppStoreApp = externalAppStoreApp;
}
}

@ -27,6 +27,7 @@ import io.entgra.device.mgt.core.application.mgt.common.response.Category;
import io.entgra.device.mgt.core.application.mgt.common.response.Tag;
import io.entgra.device.mgt.core.device.mgt.common.Base64File;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationDTO;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import io.entgra.device.mgt.core.application.mgt.common.ApplicationArtifact;
@ -273,6 +274,17 @@ public interface ApplicationManager {
*/
ApplicationDTO getApplication(int applicationId) throws ApplicationManagementException;
/**
* This method is responsible to provide application data for given deviceId.
*
* @param deviceId id of the device
* @return {@link ApplicationDTO}
* @throws ApplicationManagementException
* if an error occurred while getting subscribed app details for relevant device id,
*/
ApplicationList getSubscribedAppsOfDevice(int deviceId, PaginationRequest request)
throws ApplicationManagementException;
/**
* To get the Application for given Id.
*

@ -27,6 +27,7 @@ import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.PaginationResult;
import io.entgra.device.mgt.core.device.mgt.common.app.mgt.App;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Activity;
import java.util.List;
import java.util.Properties;
@ -207,4 +208,13 @@ public interface SubscriptionManager {
*/
PaginationResult getAppInstalledSubscribeDevices(PaginationRequest request, String appUUID, String subType,
String subTypeName) throws ApplicationManagementException;
/***
* This method is responsible for retrieving application details of the passed operation id.
* @param id ID of the related operation
* @return {@link Activity} Activity result of the app information.
* @throws {@link SubscriptionManagementException} Exception of the subscription management
*/
Activity getOperationAppDetails(String id) throws SubscriptionManagementException;
}

@ -0,0 +1,52 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.common.services;
import io.entgra.device.mgt.core.application.mgt.common.dto.ProxyResponse;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppAssetDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppAssociationDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppUserDTO;
import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException;
import java.io.IOException;
import java.util.List;
public interface VPPApplicationManager {
VppUserDTO addUser(VppUserDTO userDTO) throws ApplicationManagementException;
VppUserDTO getUserByDMUsername(String emmUsername) throws ApplicationManagementException;
void updateUser(VppUserDTO userDTO) throws ApplicationManagementException;
void syncUsers(String clientId) throws ApplicationManagementException;
void syncAssets(int nextPageIndex) throws ApplicationManagementException;
VppAssetDTO getAssetByAppId(int appId) throws ApplicationManagementException;
ProxyResponse callVPPBackend(String url, String payload, String accessToken, String method) throws IOException;
boolean addAssociation(VppAssetDTO asset, List<VppUserDTO> vppUsers) throws
ApplicationManagementException;
VppAssociationDTO getAssociation(int assetId, int userId) throws ApplicationManagementException;
VppAssociationDTO getUserAssociation(String adamId, String emmUsername) throws ApplicationManagementException;
}

@ -0,0 +1,47 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.common.wrapper;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppItuneAssetDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppItuneUserDTO;
import java.util.ArrayList;
import java.util.List;
public class VppAssociateRequestWrapper {
List<VppItuneAssetDTO> assets;
List<String> clientUserIds;
public List<VppItuneAssetDTO> getAssets() {
return assets;
}
public void setAssets(List<VppItuneAssetDTO> assets) {
this.assets = assets;
}
public List<String> getClientUserIds() {
return clientUserIds;
}
public void setClientUserIds(List<String> clientUserIds) {
this.clientUserIds = clientUserIds;
}
}

@ -0,0 +1,39 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.common.wrapper;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppAssetDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppItuneUserDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppPaginationDTO;
import java.util.ArrayList;
import java.util.List;
public class VppItuneAssetResponseWrapper extends VppPaginationDTO {
List<VppAssetDTO> assets;
public List<VppAssetDTO> getAssets() {
return assets;
}
public void setAssets(List<VppAssetDTO> assets) {
this.assets = assets;
}
}

@ -0,0 +1,40 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.common.wrapper;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppItuneUserDTO;
import java.util.ArrayList;
import java.util.List;
public class VppItuneUserRequestWrapper {
List<VppItuneUserDTO> users;
public VppItuneUserRequestWrapper() {
users = new ArrayList<>();
}
public List<VppItuneUserDTO> getUser() {
return users;
}
public void setUser(List<VppItuneUserDTO> users) {
this.users = users;
}
}

@ -0,0 +1,40 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.common.wrapper;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppItuneUserDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppPaginationDTO;
import java.util.ArrayList;
import java.util.List;
public class VppItuneUserResponseWrapper extends VppPaginationDTO {
List<VppItuneUserDTO> users;
public VppItuneUserResponseWrapper() {
users = new ArrayList<>();
}
public List<VppItuneUserDTO> getUser() {
return users;
}
public void setUser(List<VppItuneUserDTO> users) {
this.users = users;
}
}

@ -21,7 +21,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>application-mgt</artifactId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,6 +22,7 @@ import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.CategoryDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.TagDTO;
import io.entgra.device.mgt.core.application.mgt.core.exception.ApplicationManagementDAOException;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import java.util.List;
@ -150,6 +151,16 @@ public interface ApplicationDAO {
*/
ApplicationDTO getApplication(int applicationId, int tenantId) throws ApplicationManagementDAOException;
/**
* To get the application with the given id
*
* @param deviceId ID of the device which the apps are installed on.
* @param tenantId ID of the tenant.
* @return the application
* @throws ApplicationManagementDAOException ApplicationDTO Management DAO Exception.
*/
List<ApplicationDTO> getSubscribedAppsOfDevice(int deviceId, int tenantId, PaginationRequest request) throws ApplicationManagementDAOException;
/**
* To get the application with the given uuid
*

@ -23,6 +23,7 @@ import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDT
import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO;
import io.entgra.device.mgt.core.application.mgt.common.exception.SubscriptionManagementException;
import io.entgra.device.mgt.core.application.mgt.core.exception.ApplicationManagementDAOException;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Activity;
import java.util.List;
import java.util.Map;
@ -252,4 +253,15 @@ public interface SubscriptionDAO {
* @throws {@link ApplicationManagementDAOException} if connections establishment fails.
*/
Map<Integer,String> getCurrentInstalledAppVersion(int appId, List<Integer> deviceIdList, String installedVersion) throws ApplicationManagementDAOException;
/**
* Retrieves app details by operation id.
*
* @param operationId ID of the operation which app details needs to be retrieved
* @param tenantId ID of tenant
* @return {@link Activity}
* @throws ApplicationManagementDAOException if error occurred while retrieving the app details
*/
Activity getOperationAppDetails(int operationId, int tenantId) throws ApplicationManagementDAOException;
}

@ -0,0 +1,46 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.core.dao;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppAssetDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppAssociationDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppUserDTO;
import io.entgra.device.mgt.core.application.mgt.core.exception.ApplicationManagementDAOException;
public interface VppApplicationDAO {
int addVppUser(VppUserDTO userDTO, int tenantId) throws ApplicationManagementDAOException;
VppUserDTO updateVppUser(VppUserDTO userDTO, int tenantId) throws ApplicationManagementDAOException;
VppUserDTO getUserByDMUsername(String emmUsername, int tenantId) throws ApplicationManagementDAOException;
VppAssetDTO getAssetByAppId(int appId, int tenantId) throws ApplicationManagementDAOException;
int addAsset(VppAssetDTO vppAssetDTO, int tenantId) throws ApplicationManagementDAOException;
VppAssetDTO updateAsset(VppAssetDTO vppAssetDTO, int tenantId) throws ApplicationManagementDAOException;
VppAssociationDTO getAssociation(int assetId, int userId, int tenantId) throws ApplicationManagementDAOException;
int addAssociation(VppAssociationDTO vppAssociationDTO, int tenantId) throws ApplicationManagementDAOException;
VppAssociationDTO updateAssociation(VppAssociationDTO vppAssociationDTO, int tenantId) throws ApplicationManagementDAOException;
}

@ -17,7 +17,7 @@
*/
package io.entgra.device.mgt.core.application.mgt.core.dao.common;
import io.entgra.device.mgt.core.application.mgt.core.dao.SPApplicationDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.*;
import io.entgra.device.mgt.core.application.mgt.core.dao.impl.application.spapplication.GenericSPApplicationDAOImpl;
import io.entgra.device.mgt.core.application.mgt.core.dao.impl.application.spapplication.OracleSPApplicationDAOImpl;
import io.entgra.device.mgt.core.application.mgt.core.dao.impl.application.spapplication.PostgreSQLSPApplicationDAOImpl;
@ -26,16 +26,14 @@ import io.entgra.device.mgt.core.application.mgt.core.dao.impl.visibility.Generi
import io.entgra.device.mgt.core.application.mgt.core.dao.impl.visibility.OracleVisibilityDAOImpl;
import io.entgra.device.mgt.core.application.mgt.core.dao.impl.visibility.PostgreSQLVisibilityDAOImpl;
import io.entgra.device.mgt.core.application.mgt.core.dao.impl.visibility.SQLServerVisibilityDAOImpl;
import io.entgra.device.mgt.core.application.mgt.core.dao.impl.vpp.GenericVppApplicationDAOImpl;
import io.entgra.device.mgt.core.application.mgt.core.dao.impl.vpp.OracleVppApplicationDAOImpl;
import io.entgra.device.mgt.core.application.mgt.core.dao.impl.vpp.PostgreSQLVppApplicationDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.impl.vpp.SQLServerVppApplicationDAOImpl;
import io.entgra.device.mgt.core.application.mgt.core.util.Constants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import io.entgra.device.mgt.core.application.mgt.common.exception.UnsupportedDatabaseEngineException;
import io.entgra.device.mgt.core.application.mgt.core.dao.ApplicationDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.ApplicationReleaseDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.LifecycleStateDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.ReviewDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.SubscriptionDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.VisibilityDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.impl.application.PostgreSQLApplicationDAOImpl;
import io.entgra.device.mgt.core.application.mgt.core.dao.impl.application.SQLServerApplicationDAOImpl;
import io.entgra.device.mgt.core.application.mgt.core.dao.impl.application.release.OracleApplicationReleaseDAOImpl;
@ -232,4 +230,28 @@ public class ApplicationManagementDAOFactory {
}
throw new IllegalStateException("Database engine has not initialized properly.");
}
/**
* To get the instance of VppApplicationImplementation of the particular database engine.
* @return specific VppApplicationImplementation
*/
public static VppApplicationDAO getVppApplicationDAO() {
if (databaseEngine != null) {
switch (databaseEngine) {
case Constants.DataBaseTypes.DB_TYPE_H2:
case Constants.DataBaseTypes.DB_TYPE_MYSQL:
return new GenericVppApplicationDAOImpl();
case Constants.DataBaseTypes.DB_TYPE_POSTGRESQL:
return new PostgreSQLVppApplicationDAO();
case Constants.DataBaseTypes.DB_TYPE_ORACLE:
return new OracleVppApplicationDAOImpl();
case Constants.DataBaseTypes.DB_TYPE_MSSQL:
return new SQLServerVppApplicationDAOImpl();
default:
throw new UnsupportedDatabaseEngineException("Unsupported database engine : " + databaseEngine);
}
}
throw new IllegalStateException("Database engine has not initialized properly.");
}
}

@ -22,6 +22,7 @@ import io.entgra.device.mgt.core.application.mgt.core.dao.impl.AbstractDAOImpl;
import io.entgra.device.mgt.core.application.mgt.core.exception.UnexpectedServerErrorException;
import io.entgra.device.mgt.core.application.mgt.core.util.Constants;
import io.entgra.device.mgt.core.application.mgt.core.util.DAOUtil;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -656,6 +657,84 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
}
}
@Override
public List<ApplicationDTO> getSubscribedAppsOfDevice(int deviceId, int tenantId, PaginationRequest request) throws
ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Getting all installed apps of device " + deviceId
+ " from the database");
}
List<ApplicationDTO> appList = null;
String sql = "SELECT "
+ "AP_APP.ID AS APP_ID, "
+ "AP_APP.NAME AS APP_NAME, "
+ "AP_APP.DESCRIPTION AS APP_DESCRIPTION, "
+ "AP_APP.TYPE AS APP_TYPE, "
+ "AP_APP.STATUS AS APP_STATUS, "
+ "AP_APP.SUB_TYPE AS APP_SUB_TYPE, "
+ "AP_APP.CURRENCY AS APP_CURRENCY, "
+ "AP_APP.RATING AS APP_RATING, "
+ "AP_APP.DEVICE_TYPE_ID AS APP_DEVICE_TYPE_ID, "
+ "AP_APP_RELEASE.ID AS RELEASE_ID, "
+ "AP_APP_RELEASE.DESCRIPTION AS RELEASE_DESCRIPTION, "
+ "AP_APP_RELEASE.VERSION AS RELEASE_VERSION, "
+ "AP_APP_RELEASE.UUID AS RELEASE_UUID, "
+ "AP_APP_RELEASE.RELEASE_TYPE AS RELEASE_TYPE, "
+ "AP_APP_RELEASE.INSTALLER_LOCATION AS AP_RELEASE_STORED_LOC, "
+ "AP_APP_RELEASE.ICON_LOCATION AS AP_RELEASE_ICON_LOC, "
+ "AP_APP_RELEASE.BANNER_LOCATION AS AP_RELEASE_BANNER_LOC, "
+ "AP_APP_RELEASE.SC_1_LOCATION AS AP_RELEASE_SC1, "
+ "AP_APP_RELEASE.SC_2_LOCATION AS AP_RELEASE_SC2, "
+ "AP_APP_RELEASE.SC_3_LOCATION AS AP_RELEASE_SC3, "
+ "AP_APP_RELEASE.APP_HASH_VALUE AS RELEASE_HASH_VALUE, "
+ "AP_APP_RELEASE.APP_PRICE AS RELEASE_PRICE, "
+ "AP_APP_RELEASE.APP_META_INFO AS RELEASE_META_INFO, "
+ "AP_APP_RELEASE.PACKAGE_NAME AS PACKAGE_NAME, "
+ "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, "
+ "AP_APP_RELEASE.RATING AS RELEASE_RATING, "
+ "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, "
+ "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT "
+ "FROM AP_APP "
+ "JOIN AP_APP_RELEASE ON AP_APP.ID = AP_APP_RELEASE.AP_APP_ID "
+ "JOIN AP_DEVICE_SUBSCRIPTION ON AP_APP_RELEASE.ID = AP_DEVICE_SUBSCRIPTION.AP_APP_RELEASE_ID "
+ "WHERE AP_DEVICE_SUBSCRIPTION.DM_DEVICE_ID = ? AND AP_DEVICE_SUBSCRIPTION.TENANT_ID= ? "
+"AND AP_DEVICE_SUBSCRIPTION.STATUS= 'COMPLETED'";
if (request != null) {
sql = sql + " LIMIT ?,?";
}
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(1, deviceId);
stmt.setInt(2, tenantId);
if (request != null) {
stmt.setInt(3, request.getStartIndex());
stmt.setInt(4, request.getRowCount());
}
try (ResultSet rs = stmt.executeQuery()) {
appList = new ArrayList<>();
while (rs.next()) {
ApplicationDTO app = DAOUtil.loadDeviceApp(rs);
appList.add(app);
}
return appList;
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection for getting all apps installed on the device of "
+ "device Id: " + deviceId + ".";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while while running SQL to get all installed apps of device with device Id: " + deviceId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public boolean updateApplication(ApplicationDTO applicationDTO, int tenantId)
throws ApplicationManagementDAOException {

@ -21,6 +21,7 @@ import io.entgra.device.mgt.core.application.mgt.core.dao.SubscriptionDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.impl.AbstractDAOImpl;
import io.entgra.device.mgt.core.application.mgt.core.exception.UnexpectedServerErrorException;
import io.entgra.device.mgt.core.application.mgt.core.util.DAOUtil;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Activity;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus;
@ -1435,4 +1436,44 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
throw new ApplicationManagementDAOException(msg, e);
}
}
public Activity getOperationAppDetails(int operationId, int tenantId) throws ApplicationManagementDAOException {
try {
String sql = "SELECT "
+ "AP.NAME, "
+ "AP.TYPE, "
+ "AR.PACKAGE_NAME, "
+ "AR.VERSION, "
+ "DS.SUBSCRIBED_BY, "
+ "DS.STATUS, "
+ "DS.ACTION_TRIGGERED_FROM "
+ "FROM AP_APP_SUB_OP_MAPPING SOP "
+ "JOIN AP_DEVICE_SUBSCRIPTION DS ON SOP.AP_DEVICE_SUBSCRIPTION_ID = DS.ID "
+ "JOIN AP_APP_RELEASE AR ON DS.AP_APP_RELEASE_ID = AR.ID "
+ "JOIN AP_APP AP ON AP.ID = AR.AP_APP_ID "
+ " WHERE SOP.OPERATION_ID = ? AND SOP.TENANT_ID = ?";
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(1, operationId);
stmt.setInt(2,tenantId);
try (ResultSet rs = stmt.executeQuery()) {
return DAOUtil.loadOperationActivity(rs);
}
}
} catch (DBConnectionException e) {
String msg =
"Error occurred while getting the app details from the database related to operation " + operationId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred when processing SQL to retrieve app details of operation" + operationId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (UnexpectedServerErrorException e) {
String msg = "More than one app for operation " + operationId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
}

@ -0,0 +1,508 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.core.dao.impl.vpp;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppAssetDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppAssociationDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppUserDTO;
import io.entgra.device.mgt.core.application.mgt.common.exception.DBConnectionException;
import io.entgra.device.mgt.core.application.mgt.core.dao.VppApplicationDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.impl.AbstractDAOImpl;
import io.entgra.device.mgt.core.application.mgt.core.exception.ApplicationManagementDAOException;
import io.entgra.device.mgt.core.application.mgt.core.exception.UnexpectedServerErrorException;
import io.entgra.device.mgt.core.application.mgt.core.util.DAOUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.sql.*;
import java.util.List;
public class GenericVppApplicationDAOImpl extends AbstractDAOImpl implements VppApplicationDAO {
private static final Log log = LogFactory.getLog(GenericVppApplicationDAOImpl.class);
@Override
public int addVppUser(VppUserDTO userDTO, int tenantId)
throws ApplicationManagementDAOException {
int vppUserId = -1;
String sql = "INSERT INTO "
+ "AP_VPP_USER("
+ "CLIENT_USER_ID, "
+ "DM_USERNAME, "
+ "TENANT_ID, "
+ "EMAIL, "
+ "INVITE_CODE, "
+ "STATUS,"
+ "CREATED_TIME,"
+ "LAST_UPDATED_TIME,"
+ "MANAGED_ID,"
+ "TEMP_PASSWORD) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
long currentTime = System.currentTimeMillis();
stmt.setString(1, userDTO.getClientUserId());
stmt.setString(2, userDTO.getDmUsername());
stmt.setInt(3, tenantId);
stmt.setString(4, userDTO.getEmail());
stmt.setString(5, userDTO.getInviteCode());
stmt.setString(6, userDTO.getStatus());
stmt.setLong(7, currentTime);
stmt.setLong(8, currentTime);
stmt.setString(9, userDTO.getManagedId());
stmt.setString(10, userDTO.getTmpPassword());
stmt.executeUpdate();
try (ResultSet rs = stmt.getGeneratedKeys()) {
if (rs.next()) {
vppUserId = rs.getInt(1);
}
}
return vppUserId;
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining database connection when adding the vpp user";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred when processing SQL to add the vpp user.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public VppUserDTO updateVppUser(VppUserDTO userDTO, int tenantId)
throws ApplicationManagementDAOException {
String sql = "UPDATE AP_VPP_USER SET ";
if (userDTO.getClientUserId() != null && !userDTO.getClientUserId().isEmpty()) {
sql += "CLIENT_USER_ID = ?,";
}
if (userDTO.getDmUsername() != null && !userDTO.getDmUsername().isEmpty()) {
sql += "DM_USERNAME = ?,";
}
if (userDTO.getEmail() != null && !userDTO.getEmail().isEmpty()) {
sql += "EMAIL = ?,";
}
if (userDTO.getInviteCode() != null && !userDTO.getInviteCode().isEmpty()) {
sql += "INVITE_CODE = ?,";
}
if (userDTO.getStatus() != null && !userDTO.getStatus().isEmpty()) {
sql += "STATUS = ?,";
}
if (userDTO.getManagedId() != null && !userDTO.getManagedId().isEmpty()) {
sql += "MANAGED_ID = ?,";
}
if (userDTO.getTmpPassword() != null && !userDTO.getTmpPassword().isEmpty()) {
sql += "TEMP_PASSWORD = ?,";
}
sql += " TENANT_ID = ?, LAST_UPDATED_TIME = ? WHERE ID = ?";
try {
Connection conn = this.getDBConnection();
long updatedTime = System.currentTimeMillis();
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
int x = 0;
if (userDTO.getClientUserId() != null && !userDTO.getClientUserId().isEmpty()) {
stmt.setString(++x, userDTO.getClientUserId());
}
if (userDTO.getDmUsername() != null && !userDTO.getDmUsername().isEmpty()) {
stmt.setString(++x, userDTO.getDmUsername());
}
if (userDTO.getEmail() != null && !userDTO.getEmail().isEmpty()) {
stmt.setString(++x, userDTO.getEmail());
}
if (userDTO.getInviteCode() != null && !userDTO.getInviteCode().isEmpty()) {
stmt.setString(++x, userDTO.getInviteCode());
}
if (userDTO.getStatus() != null && !userDTO.getStatus().isEmpty()) {
stmt.setString(++x, userDTO.getStatus());
}
if (userDTO.getManagedId() != null && !userDTO.getManagedId().isEmpty()) {
stmt.setString(++x, userDTO.getManagedId());
}
if (userDTO.getTmpPassword() != null && !userDTO.getTmpPassword().isEmpty()) {
stmt.setString(++x, userDTO.getTmpPassword());
}
stmt.setInt(++x, tenantId);
stmt.setLong(++x, updatedTime);
stmt.setInt(++x, userDTO.getId());
if (stmt.executeUpdate() == 1) {
return userDTO;
}
return null;
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining database connection when updating the vpp user";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred when processing SQL to updating the vpp user.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public VppUserDTO getUserByDMUsername(String emmUsername, int tenantId)
throws ApplicationManagementDAOException {
String sql = "SELECT "
+ "ID, "
+ "CLIENT_USER_ID, "
+ "TENANT_ID, "
+ "EMAIL, "
+ "INVITE_CODE, "
+ "STATUS, "
+ "CREATED_TIME, "
+ "LAST_UPDATED_TIME, "
+ "MANAGED_ID, "
+ "TEMP_PASSWORD, "
+ "DM_USERNAME "
+ "FROM AP_VPP_USER "
+ "WHERE DM_USERNAME = ? AND TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, emmUsername);
stmt.setInt(2, tenantId);
try (ResultSet rs = stmt.executeQuery()) {
return DAOUtil.loadVppUser(rs);
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining database connection when retrieving vpp user by EMM Username.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred when processing SQL to retrieve vpp user by EMM Username.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (UnexpectedServerErrorException e) {
String msg = "Found more than one user for: " + emmUsername;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public VppAssetDTO getAssetByAppId(int appId, int tenantId)
throws ApplicationManagementDAOException {
String sql = "SELECT "
+ "ID, "
+ "APP_ID, "
+ "TENANT_ID, "
+ "CREATED_TIME, "
+ "LAST_UPDATED_TIME, "
+ "ADAM_ID, "
+ "ASSIGNED_COUNT, "
+ "DEVICE_ASSIGNABLE, "
+ "PRICING_PARAMS, "
+ "PRODUCT_TYPE, "
+ "RETIRED_COUNT, "
+ "REVOCABLE "
// + "SUPPORTED_PLATFORMS "
+ "FROM AP_ASSETS "
+ "WHERE APP_ID = ? AND TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(1, appId);
stmt.setInt(2, tenantId);
try (ResultSet rs = stmt.executeQuery()) {
return DAOUtil.loadAsset(rs);
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining database connection when retrieving asset data of app id "+ appId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred when processing SQL to retrieve asset by app id.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (UnexpectedServerErrorException e) {
String msg = "Found more than one app for app id: " + appId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public int addAsset(VppAssetDTO vppAssetDTO, int tenantId)
throws ApplicationManagementDAOException {
int assetId = -1;
String sql = "INSERT INTO "
+ "AP_ASSETS("
+ "APP_ID, "
+ "TENANT_ID, "
+ "CREATED_TIME,"
+ "LAST_UPDATED_TIME,"
+ "ADAM_ID,"
+ "ASSIGNED_COUNT,"
+ "DEVICE_ASSIGNABLE,"
+ "PRICING_PARAMS,"
+ "PRODUCT_TYPE,"
+ "RETIRED_COUNT,"
+ "REVOCABLE, "
+ "SUPPORTED_PLATFORMS) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
long currentTime = System.currentTimeMillis();
stmt.setInt(1, vppAssetDTO.getAppId());
stmt.setInt(2, tenantId);
stmt.setLong(3, currentTime);
stmt.setLong(4, currentTime);
stmt.setString(5, vppAssetDTO.getAdamId());
stmt.setString(6, vppAssetDTO.getAssignedCount());
stmt.setString(7, vppAssetDTO.getDeviceAssignable());
stmt.setString(8, vppAssetDTO.getPricingParam());
stmt.setString(9, vppAssetDTO.getProductType());
stmt.setString(10, vppAssetDTO.getRetiredCount());
stmt.setString(11, vppAssetDTO.getRevocable());
List<String> platformList = vppAssetDTO.getSupportedPlatforms();
String platformString = String.join(",", platformList);
stmt.setString(12, platformString);
stmt.executeUpdate();
try (ResultSet rs = stmt.getGeneratedKeys()) {
if (rs.next()) {
assetId = rs.getInt(1);
}
}
return assetId;
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining database connection when adding the asset.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred when processing SQL to add the asset.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public VppAssetDTO updateAsset(VppAssetDTO vppAssetDTO, int tenantId)
throws ApplicationManagementDAOException {
String sql = "UPDATE AP_ASSETS SET ";
if (vppAssetDTO.getAdamId() != null && !vppAssetDTO.getAdamId().isEmpty()) {
sql += "ADAM_ID = ?, ";
}
if (vppAssetDTO.getAssignedCount() != null && !vppAssetDTO.getAssignedCount().isEmpty()) {
sql += "ASSIGNED_COUNT = ?, ";
}
if (vppAssetDTO.getDeviceAssignable() != null && !vppAssetDTO.getDeviceAssignable().isEmpty()) {
sql += "DEVICE_ASSIGNABLE = ?, ";
}
if (vppAssetDTO.getPricingParam() != null && !vppAssetDTO.getPricingParam().isEmpty()) {
sql += "PRICING_PARAMS = ?, ";
}
if (vppAssetDTO.getProductType() != null && !vppAssetDTO.getProductType().isEmpty()) {
sql += "PRODUCT_TYPE = ?, ";
}
if (vppAssetDTO.getRetiredCount() != null && !vppAssetDTO.getRetiredCount().isEmpty()) {
sql += "RETIRED_COUNT = ?, ";
}
if (vppAssetDTO.getRevocable() != null && !vppAssetDTO.getRevocable().isEmpty()) {
sql += "REVOCABLE = ?, ";
}
if (vppAssetDTO.getSupportedPlatforms() != null && !vppAssetDTO.getSupportedPlatforms().isEmpty()) {
sql += "SUPPORTED_PLATFORMS = ?,";
}
sql += "APP_ID = ?, LAST_UPDATED_TIME = ? WHERE ID = ? AND TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
long updatedTime = System.currentTimeMillis();
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
int x = 0;
if (vppAssetDTO.getAdamId() != null && !vppAssetDTO.getAdamId().isEmpty()) {
stmt.setString(++x, vppAssetDTO.getAdamId());
}
if (vppAssetDTO.getAssignedCount() != null && !vppAssetDTO.getAssignedCount().isEmpty()) {
stmt.setString(++x, vppAssetDTO.getAssignedCount());
}
if (vppAssetDTO.getDeviceAssignable() != null && !vppAssetDTO.getDeviceAssignable().isEmpty()) {
stmt.setString(++x, vppAssetDTO.getDeviceAssignable());
}
if (vppAssetDTO.getPricingParam() != null && !vppAssetDTO.getPricingParam().isEmpty()) {
stmt.setString(++x, vppAssetDTO.getPricingParam());
}
if (vppAssetDTO.getProductType() != null && !vppAssetDTO.getProductType().isEmpty()) {
stmt.setString(++x, vppAssetDTO.getProductType());
}
if (vppAssetDTO.getRetiredCount() != null && !vppAssetDTO.getRetiredCount().isEmpty()) {
stmt.setString(++x, vppAssetDTO.getRetiredCount());
}
if (vppAssetDTO.getRevocable() != null && !vppAssetDTO.getRevocable().isEmpty()) {
stmt.setString(++x, vppAssetDTO.getRevocable());
}
if (vppAssetDTO.getSupportedPlatforms() != null && !vppAssetDTO.getSupportedPlatforms().isEmpty()) {
List<String> platformList = vppAssetDTO.getSupportedPlatforms();
String platformString = String.join(",", platformList);
stmt.setString(++x, platformString);
}
stmt.setInt(++x, vppAssetDTO.getAppId());
stmt.setLong(++x, updatedTime);
stmt.setInt(++x, vppAssetDTO.getId());
stmt.setLong(++x, tenantId);
if (stmt.executeUpdate() == 1) {
return vppAssetDTO;
}
return null;
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining database connection when updating the vpp user";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred when processing SQL to updating the vpp user.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public VppAssociationDTO getAssociation(int assetId, int userId, int tenantId)
throws ApplicationManagementDAOException {
String sql = "SELECT "
+ "ID, "
+ "ASSOCIATION_TYPE, "
+ "CREATED_TIME, "
+ "LAST_UPDATED_TIME, "
+ "PRICING_PARAMS "
+ "FROM AP_VPP_ASSOCIATION "
+ "WHERE ASSET_ID = ? AND USER_ID = ? AND TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(1, assetId);
stmt.setInt(2, userId);
stmt.setInt(3, tenantId);
try (ResultSet rs = stmt.executeQuery()) {
return DAOUtil.loadAssignment(rs);
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining database connection when retrieving assignment data of user with id "+ userId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred when processing SQL to retrieve assignment by asset id and user id.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (UnexpectedServerErrorException e) {
String msg = "Found more than one assignment for user id: " + userId + " and asset id: " + assetId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public int addAssociation(VppAssociationDTO vppAssociationDTO, int tenantId)
throws ApplicationManagementDAOException {
int associationId = -1;
String sql = "INSERT INTO "
+ "AP_VPP_ASSOCIATION("
+ "ASSET_ID, "
+ "USER_ID, "
+ "TENANT_ID, "
+ "ASSOCIATION_TYPE,"
+ "CREATED_TIME,"
+ "LAST_UPDATED_TIME,"
+ "PRICING_PARAMS) "
+ "VALUES (?, ?, ?, ?, ?)";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
long currentTime = System.currentTimeMillis();
stmt.setInt(1, vppAssociationDTO.getAssetId());
stmt.setInt(2, vppAssociationDTO.getClientId());
stmt.setInt(3, tenantId);
stmt.setString(4, vppAssociationDTO.getAssociationType());
stmt.setLong(5, currentTime);
stmt.setLong(6, currentTime);
stmt.setString(7, vppAssociationDTO.getPricingParam());
stmt.executeUpdate();
try (ResultSet rs = stmt.getGeneratedKeys()) {
if (rs.next()) {
associationId = rs.getInt(1);
}
}
return associationId;
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining database connection when adding the asset.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred when processing SQL to add the asset.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public VppAssociationDTO updateAssociation(VppAssociationDTO vppAssociationDTO, int tenantId)
throws ApplicationManagementDAOException {
String sql = "UPDATE "
+ "AP_VPP_ASSOCIATION "
+ "SET "
+ "ASSET_ID = ?,"
+ "USER_ID = ?, "
+ "ASSOCIATION_TYPE = ?, "
+ "LAST_UPDATED_TIME = ?, "
+ "PRICING_PARAMS = ? "
+ "WHERE ID = ? AND TENANT_ID = ?";
try {
Connection conn = this.getDBConnection();
long updatedTime = System.currentTimeMillis();
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(1, vppAssociationDTO.getAssetId());
stmt.setInt(2, vppAssociationDTO.getClientId());
stmt.setString(3, vppAssociationDTO.getAssociationType());
stmt.setLong(4, updatedTime);
stmt.setString(5, vppAssociationDTO.getPricingParam());
stmt.setInt(6, vppAssociationDTO.getId());
stmt.setLong(7, tenantId);
if (stmt.executeUpdate() == 1) {
return vppAssociationDTO;
}
return null;
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining database connection when updating the vpp user";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred when processing SQL to updating the vpp user.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
}

@ -0,0 +1,82 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.core.dao.impl.vpp;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppUserDTO;
import io.entgra.device.mgt.core.application.mgt.common.exception.DBConnectionException;
import io.entgra.device.mgt.core.application.mgt.core.exception.ApplicationManagementDAOException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.sql.*;
public class OracleVppApplicationDAOImpl extends GenericVppApplicationDAOImpl {
private static final Log log = LogFactory.getLog(GenericVppApplicationDAOImpl.class);
@Override
public int addVppUser(VppUserDTO userDTO, int tenantId)
throws ApplicationManagementDAOException {
int vppUserId = -1;
String sql = "INSERT INTO "
+ "AP_VPP_USER("
+ "CLIENT_USER_ID, "
+ "DM_USERNAME, "
+ "TENANT_ID, "
+ "EMAIL, "
+ "INVITE_CODE, "
+ "STATUS,"
+ "CREATED_TIME,"
+ "LAST_UPDATED_TIME,"
+ "MANAGED_ID,"
+ "TEMP_PASSWORD) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, new String[] {"ID"})) {
long currentTime = System.currentTimeMillis();
stmt.setString(1, userDTO.getClientUserId());
stmt.setString(2, userDTO.getDmUsername());
stmt.setInt(3, tenantId);
stmt.setString(4, userDTO.getEmail());
stmt.setString(5, userDTO.getInviteCode());
stmt.setString(6, userDTO.getStatus());
stmt.setLong(7, currentTime);
stmt.setLong(8, currentTime);
stmt.setString(9, userDTO.getManagedId());
stmt.setString(10, userDTO.getTmpPassword());
stmt.executeUpdate();
try (ResultSet rs = stmt.getGeneratedKeys()) {
if (rs.next()) {
vppUserId = rs.getInt(1);
}
}
return vppUserId;
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining database connection when adding the vpp user";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred when processing SQL to add the vpp user.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
}

@ -0,0 +1,81 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.core.dao.impl.vpp;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppUserDTO;
import io.entgra.device.mgt.core.application.mgt.common.exception.DBConnectionException;
import io.entgra.device.mgt.core.application.mgt.core.exception.ApplicationManagementDAOException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.sql.*;
public class PostgreSQLVppApplicationDAO extends GenericVppApplicationDAOImpl {
private static final Log log = LogFactory.getLog(GenericVppApplicationDAOImpl.class);
public int addVppUser(VppUserDTO userDTO, int tenantId)
throws ApplicationManagementDAOException {
int vppUserId = -1;
String sql = "INSERT INTO "
+ "AP_VPP_USER("
+ "CLIENT_USER_ID, "
+ "DM_USERNAME, "
+ "TENANT_ID, "
+ "EMAIL, "
+ "INVITE_CODE, "
+ "STATUS,"
+ "CREATED_TIME,"
+ "LAST_UPDATED_TIME,"
+ "MANAGED_ID,"
+ "TEMP_PASSWORD) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
try {
Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql, new String[]{"ID"})) {
long currentTime = System.currentTimeMillis();
stmt.setString(1, userDTO.getClientUserId());
stmt.setString(2, userDTO.getDmUsername());
stmt.setInt(3, tenantId);
stmt.setString(4, userDTO.getEmail());
stmt.setString(5, userDTO.getInviteCode());
stmt.setString(6, userDTO.getStatus());
stmt.setLong(7, currentTime);
stmt.setLong(8, currentTime);
stmt.setString(9, userDTO.getManagedId());
stmt.setString(10, userDTO.getTmpPassword());
stmt.executeUpdate();
try (ResultSet rs = stmt.getGeneratedKeys()) {
if (rs.next()) {
vppUserId = rs.getInt(1);
}
}
return vppUserId;
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining database connection when adding the vpp user";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred when processing SQL to add the vpp user.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
}

@ -0,0 +1,22 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.core.dao.impl.vpp;
public class SQLServerVppApplicationDAOImpl extends GenericVppApplicationDAOImpl {
}

@ -22,6 +22,7 @@ import io.entgra.device.mgt.core.application.mgt.core.exception.BadRequestExcept
import io.entgra.device.mgt.core.device.mgt.common.Base64File;
import io.entgra.device.mgt.core.application.mgt.core.dao.SPApplicationDAO;
import io.entgra.device.mgt.core.application.mgt.core.util.ApplicationManagementUtil;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata;
import org.apache.commons.codec.digest.DigestUtils;
@ -1444,6 +1445,43 @@ public class ApplicationManagerImpl implements ApplicationManager {
}
}
@Override
public ApplicationList getSubscribedAppsOfDevice(int deviceId, PaginationRequest request) throws ApplicationManagementException {
ApplicationList applicationList = new ApplicationList();
List<Application> applications = new ArrayList<>();
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
try {
ConnectionManagerUtil.openDBConnection();
List<ApplicationDTO> applicationDTOS = this.applicationDAO.getSubscribedAppsOfDevice(deviceId, tenantId, request);
for (ApplicationDTO applicationDTO: applicationDTOS) {
applicationDTO.setTags(this.applicationDAO.getAppTags(applicationDTO.getId(), tenantId));
applicationDTO.setAppCategories(this.applicationDAO.getAppCategories(applicationDTO.getId(), tenantId));
applications.add(APIUtil.appDtoToAppResponse(applicationDTO));
}
List<ApplicationDTO> totalApplications = this.applicationDAO.getSubscribedAppsOfDevice(deviceId, tenantId, null);
Pagination pagination = new Pagination();
pagination.setCount(totalApplications.size());
pagination.setSize(applications.size());
pagination.setOffset(request.getStartIndex());
pagination.setLimit(request.getRowCount());
applicationList.setApplications(applications);
applicationList.setPagination(pagination);
return applicationList;
} catch (ApplicationManagementDAOException e) {
String msg = "Error occurred when getting installed apps of device with device id: "
+ deviceId;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (DBConnectionException e) {
String msg = "DB Connection error occurred while getting installed apps of device with device id: " + deviceId;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
/**
* Check whether given OS range is valid or invalid
*

@ -19,7 +19,14 @@
package io.entgra.device.mgt.core.application.mgt.core.impl;
import com.google.gson.Gson;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppAssetDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppUserDTO;
import io.entgra.device.mgt.core.application.mgt.common.services.VPPApplicationManager;
import io.entgra.device.mgt.core.application.mgt.core.dao.VppApplicationDAO;
import io.entgra.device.mgt.core.application.mgt.core.exception.BadRequestException;
import io.entgra.device.mgt.core.device.mgt.core.DeviceManagementConstants;
import io.entgra.device.mgt.core.application.mgt.core.exception.UnexpectedServerErrorException;
import io.entgra.device.mgt.core.application.mgt.core.util.VppHttpUtil;
import io.entgra.device.mgt.core.device.mgt.extensions.logger.spi.EntgraLogger;
import io.entgra.device.mgt.core.notification.logger.AppInstallLogContext;
import io.entgra.device.mgt.core.notification.logger.impl.EntgraAppInstallLoggerImpl;
@ -118,12 +125,14 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
private static final EntgraLogger log = new EntgraAppInstallLoggerImpl(SubscriptionManagerImpl.class);
private SubscriptionDAO subscriptionDAO;
private ApplicationDAO applicationDAO;
private VppApplicationDAO vppApplicationDAO;
private LifecycleStateManager lifecycleStateManager;
public SubscriptionManagerImpl() {
this.lifecycleStateManager = DataHolder.getInstance().getLifecycleStateManager();
this.subscriptionDAO = ApplicationManagementDAOFactory.getSubscriptionDAO();
this.applicationDAO = ApplicationManagementDAOFactory.getApplicationDAO();
this.vppApplicationDAO = ApplicationManagementDAOFactory.getVppApplicationDAO();
}
@Override
@ -148,6 +157,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
ApplicationDTO applicationDTO = getApplicationDTO(applicationUUID);
ApplicationSubscriptionInfo applicationSubscriptionInfo = getAppSubscriptionInfo(applicationDTO, subType,
params);
performExternalStoreSubscription(applicationDTO, applicationSubscriptionInfo);
ApplicationInstallResponse applicationInstallResponse = performActionOnDevices(
applicationSubscriptionInfo.getAppSupportingDeviceTypeName(), applicationSubscriptionInfo.getDevices(),
applicationDTO, subType, applicationSubscriptionInfo.getSubscribers(), action, properties, isOperationReExecutingDisabled);
@ -156,6 +166,51 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
return applicationInstallResponse;
}
private void performExternalStoreSubscription(ApplicationDTO applicationDTO,
ApplicationSubscriptionInfo
applicationSubscriptionInfo) throws ApplicationManagementException {
try {
// Only for iOS devices
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
if (DeviceTypes.IOS.toString().equalsIgnoreCase(APIUtil.getDeviceTypeData(applicationDTO
.getDeviceTypeId()).getName())) {
// TODO: replace getAssetByAppId with the correct one in DAO
// Check if the app trying to subscribe is a VPP asset.
VppAssetDTO storedAsset = vppApplicationDAO.getAssetByAppId(applicationDTO.getId(), tenantId);
if (storedAsset != null) { // This is a VPP asset
List<VppUserDTO> users = new ArrayList<>();
List<Device> devices = applicationSubscriptionInfo.getDevices();// get
// subscribed device list, so that we can extract the users of those devices.
for (Device device : devices) {
VppUserDTO user = vppApplicationDAO.getUserByDMUsername(device.getEnrolmentInfo()
.getOwner(), PrivilegedCarbonContext.getThreadLocalCarbonContext()
.getTenantId(true));
users.add(user);
}
VPPApplicationManager vppManager = APIUtil.getVPPManager();
vppManager.addAssociation(storedAsset, users);
}
}
} catch (BadRequestException e) {
String msg = "Device Type not found";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (UnexpectedServerErrorException e) {
String msg = "Unexpected error while getting device type";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementDAOException e) {
String msg = "Error while getting the device user";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementException e) {
String msg = "Error while associating user";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
}
}
@Override
public void createScheduledSubscription(ScheduledSubscriptionDTO subscriptionDTO)
throws SubscriptionManagementException {
@ -1568,4 +1623,29 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public Activity getOperationAppDetails(String id) throws SubscriptionManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
int operationId = Integer.parseInt(
id.replace(DeviceManagementConstants.OperationAttributes.ACTIVITY, ""));
if (operationId == 0) {
throw new IllegalArgumentException("Operation ID cannot be null or zero (0).");
}
try {
ConnectionManagerUtil.openDBConnection();
return subscriptionDAO.getOperationAppDetails(operationId, tenantId);
} catch (ApplicationManagementDAOException e) {
String msg = "Error occurred while retrieving app details of operation: " + operationId;
log.error(msg, e);
throw new SubscriptionManagementException(msg, e);
} catch (DBConnectionException e) {
String msg = "Error occurred while retrieving the database connection";
log.error(msg, e);
throw new SubscriptionManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
}

@ -0,0 +1,610 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.core.impl;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import io.entgra.device.mgt.core.application.mgt.common.DepConfig;
import io.entgra.device.mgt.core.application.mgt.common.dto.ItuneAppDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ProxyResponse;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppAssetDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppAssociationDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppItuneAssetDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppItuneUserDTO;
import io.entgra.device.mgt.core.application.mgt.common.response.Application;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppUserDTO;
import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException;
import io.entgra.device.mgt.core.application.mgt.common.exception.DBConnectionException;
import io.entgra.device.mgt.core.application.mgt.common.exception.TransactionManagementException;
import io.entgra.device.mgt.core.application.mgt.common.services.VPPApplicationManager;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.VppAssociateRequestWrapper;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.VppItuneAssetResponseWrapper;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.VppItuneUserRequestWrapper;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.VppItuneUserResponseWrapper;
import io.entgra.device.mgt.core.application.mgt.core.dao.ApplicationDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.SPApplicationDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.VisibilityDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.VppApplicationDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.common.ApplicationManagementDAOFactory;
import io.entgra.device.mgt.core.application.mgt.core.exception.ApplicationManagementDAOException;
import io.entgra.device.mgt.core.application.mgt.core.internal.DataHolder;
import io.entgra.device.mgt.core.application.mgt.core.lifecycle.LifecycleStateManager;
import io.entgra.device.mgt.core.application.mgt.core.util.ApplicationManagementUtil;
import io.entgra.device.mgt.core.application.mgt.core.util.ConnectionManagerUtil;
import io.entgra.device.mgt.core.application.mgt.core.util.Constants;
import io.entgra.device.mgt.core.application.mgt.core.util.VppHttpUtil;
import io.entgra.device.mgt.core.application.mgt.core.util.APIUtil;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService;
import io.entgra.device.mgt.core.device.mgt.core.DeviceManagementConstants;
import io.entgra.device.mgt.core.device.mgt.core.internal.DeviceManagementDataHolder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpStatus;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class VppApplicationManagerImpl implements VPPApplicationManager {
private static final String APP_API = "https://vpp.itunes.apple.com/mdm/v2";
private static final String ASSETS = APP_API + "/assets";
private static final String USER_CREATE = APP_API + "/users/create";
private static final String USER_UPDATE = APP_API + "/users/update";
private static final String USER_GET = APP_API + "/users";
private static final String ASSIGNMENTS_POST = APP_API + "/assets/associate";
private static final String ASSIGNMENTS_GET = APP_API + "/assignments";
private static final String TOKEN = "";
private static final String LOOKUP_API = "https://uclient-api.itunes.apple" +
".com/WebObjects/MZStorePlatform.woa/wa/lookup?version=2&id=";
private static final String LOOKUP_API_PREFIX =
"&p=mdm-lockup&caller=MDM&platform=enterprisestore&cc=us&l=en";
private static final Log log = LogFactory.getLog(VppApplicationManagerImpl.class);
private ApplicationDAO applicationDAO;
private SPApplicationDAO spApplicationDAO;
private VisibilityDAO visibilityDAO;
private final LifecycleStateManager lifecycleStateManager;
private VppApplicationDAO vppApplicationDAO;
public VppApplicationManagerImpl() {
initDataAccessObjects();
lifecycleStateManager = DataHolder.getInstance().getLifecycleStateManager();
}
private void initDataAccessObjects() {
this.applicationDAO = ApplicationManagementDAOFactory.getApplicationDAO();
this.visibilityDAO = ApplicationManagementDAOFactory.getVisibilityDAO();
this.spApplicationDAO = ApplicationManagementDAOFactory.getSPApplicationDAO();
this.vppApplicationDAO = ApplicationManagementDAOFactory.getVppApplicationDAO();
}
@Override
public VppUserDTO addUser(VppUserDTO userDTO) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
// Call the API to add
try {
VppItuneUserDTO ituneUserDTO = userDTO;
VppItuneUserRequestWrapper wrapper = new VppItuneUserRequestWrapper();
wrapper.getUser().add(ituneUserDTO);
Gson gson = new Gson();
String userPayload = gson.toJson(wrapper);
ProxyResponse proxyResponse = callVPPBackend(USER_CREATE, userPayload, getVppToken(), Constants.VPP.POST);
if ((proxyResponse.getCode() == HttpStatus.SC_OK || proxyResponse.getCode() ==
HttpStatus.SC_CREATED) && proxyResponse.getData().contains(Constants.VPP.EVENT_ID)) {
// Create user does not return any useful data. Its needed to call the backend again
ProxyResponse getUserResponse = callVPPBackend(USER_GET + Constants.VPP.CLIENT_USER_ID_PARAM +
userDTO.getClientUserId(), userPayload, getVppToken(), Constants.VPP.GET);
if ((getUserResponse.getCode() == HttpStatus.SC_OK || getUserResponse.getCode() ==
HttpStatus.SC_CREATED) && getUserResponse.getData().contains(Constants.VPP.TOTAL_PAGES)) {
VppItuneUserResponseWrapper vppItuneUserResponseWrapper = gson.fromJson
(getUserResponse.getData(), VppItuneUserResponseWrapper.class);
userDTO.setInviteCode(vppItuneUserResponseWrapper.getUser().get(0)
.getInviteCode());
userDTO.setStatus(vppItuneUserResponseWrapper.getUser().get(0).getStatus());
log.error("userDTO " + userDTO.toString());
try {
ConnectionManagerUtil.beginDBTransaction();
int id = vppApplicationDAO.addVppUser(userDTO, tenantId);
if (id != -1) {
ConnectionManagerUtil.commitDBTransaction();
userDTO.setId(id);
userDTO.setTenantId(PrivilegedCarbonContext
.getThreadLocalCarbonContext().getTenantId());
return userDTO;
}
ConnectionManagerUtil.rollbackDBTransaction();
return null;
} catch (ApplicationManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while adding the Vpp User.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (TransactionManagementException e) {
String msg = "Error occurred while executing database transaction for adding Vpp User.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (DBConnectionException e) {
String msg = "Error occurred while retrieving the database connection for adding Vpp User.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
}
} catch (IOException e) {
String msg = "Error while calling VPP backend to add user";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
}
return null;
}
@Override
public VppUserDTO getUserByDMUsername(String emmUsername) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
try {
ConnectionManagerUtil.openDBConnection();
return vppApplicationDAO.getUserByDMUsername(emmUsername, tenantId);
} catch (DBConnectionException e) {
String msg = "DB Connection error occurs while getting vpp User data related to EMM user " + emmUsername + ".";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementDAOException e) {
String msg = "Error occurred while getting vpp User data related to EMM user " + emmUsername + ".";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public void updateUser(VppUserDTO userDTO) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
VppItuneUserDTO ituneUserDTO = userDTO;
VppItuneUserRequestWrapper wrapper = new VppItuneUserRequestWrapper();
wrapper.getUser().add(ituneUserDTO);
Gson gson = new Gson();
String userPayload = gson.toJson(wrapper);
try {
ProxyResponse proxyResponse = callVPPBackend(USER_UPDATE, userPayload, getVppToken(), Constants.VPP.POST);
if ((proxyResponse.getCode() == HttpStatus.SC_OK || proxyResponse.getCode() ==
HttpStatus.SC_CREATED) && proxyResponse.getData().contains(Constants.VPP.EVENT_ID)) {
VppUserDTO currentUserDTO = getUserByDMUsername(userDTO.getDmUsername());
if (currentUserDTO != null) {
userDTO.setId(currentUserDTO.getId());
}
try {
ConnectionManagerUtil.beginDBTransaction();
if (vppApplicationDAO.updateVppUser(userDTO, tenantId) == null) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Unable to update the Vpp user " +userDTO.getId();
log.error(msg);
throw new ApplicationManagementException(msg);
}
ConnectionManagerUtil.commitDBTransaction();
} catch (ApplicationManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while updating the Vpp User.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (TransactionManagementException e) {
String msg = "Error occurred while executing database transaction for Vpp User update.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (DBConnectionException e) {
String msg = "Error occurred while retrieving the database connection for Vpp User update.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
} catch (IOException e) {
String msg = "Error while calling VPP backend to update";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
}
}
@Override
public void syncUsers(String clientId) throws ApplicationManagementException {
ProxyResponse proxyResponse = null;
try {
proxyResponse = callVPPBackend(USER_GET, null, getVppToken(), Constants
.VPP.GET);
if ((proxyResponse.getCode() == HttpStatus.SC_OK || proxyResponse.getCode() ==
HttpStatus.SC_CREATED) && proxyResponse.getData().contains(Constants.VPP.TOTAL_PAGES)) {
log.error("proxyResponse " + proxyResponse.getData());
Gson gson = new Gson();
VppItuneUserResponseWrapper vppUserResponseWrapper = gson.fromJson
(proxyResponse.getData(), VppItuneUserResponseWrapper.class);
// TODO: to implement later
}
} catch (IOException e) {
String msg = "Error while syncing VPP users with backend";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
}
}
@Override
public void syncAssets(int nextPageIndex) throws ApplicationManagementException {
ProxyResponse proxyResponse = null;
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
try {
String url = ASSETS;
if (nextPageIndex > 0) { // Not the first page
url += "?pageIndex=" + nextPageIndex;
}
proxyResponse = callVPPBackend(url, null, getVppToken(), Constants.VPP.GET);
if ((proxyResponse.getCode() == HttpStatus.SC_OK || proxyResponse.getCode() ==
HttpStatus.SC_CREATED) && proxyResponse.getData().contains(Constants.VPP.TOTAL_PAGES)) {
Gson gson = new Gson();
VppItuneAssetResponseWrapper vppItuneAssetResponse = gson.fromJson
(proxyResponse.getData(), VppItuneAssetResponseWrapper.class);
if (vppItuneAssetResponse.getSize() > 0) {
for (VppAssetDTO vppAssetDTO : vppItuneAssetResponse.getAssets()) {
vppAssetDTO.setTenantId(PrivilegedCarbonContext
.getThreadLocalCarbonContext().getTenantId());
vppAssetDTO.setCreatedTime(String.valueOf(System.currentTimeMillis()));
vppAssetDTO.setLastUpdatedTime(String.valueOf(System.currentTimeMillis()));
}
for (VppAssetDTO vppAssetDTO : vppItuneAssetResponse.getAssets()) {
ItuneAppDTO ituneAppDTO = lookupAsset(vppAssetDTO.getAdamId());
ApplicationManagementUtil.persistApp(ituneAppDTO);
List<Application> applications = ApplicationManagementUtil.getAppDetails(vppAssetDTO.getAdamId());
for (Application application :applications) {
VppAssetDTO vppAssetDTOs = getAssetByAppId(application.getId());
if (vppAssetDTOs == null) {
vppAssetDTOs = new VppAssetDTO();
vppAssetDTO.setAppId(application.getId());
try {
ConnectionManagerUtil.beginDBTransaction();
if (vppApplicationDAO.addAsset(vppAssetDTO, tenantId) != -1) {
ConnectionManagerUtil.commitDBTransaction();
}
ConnectionManagerUtil.rollbackDBTransaction();
} catch (ApplicationManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while adding the Asset.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (TransactionManagementException e) {
String msg = "Error occurred while executing database transaction for adding Asset.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (DBConnectionException e) {
String msg = "Error occurred while retrieving the database connection for adding Asset.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
} else {
vppAssetDTOs.setAppId(application.getId());
vppAssetDTOs.setSupportedPlatforms(vppAssetDTO.getSupportedPlatforms());
try {
ConnectionManagerUtil.beginDBTransaction();
if (vppApplicationDAO.updateAsset(vppAssetDTOs, tenantId) == null) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Unable to update the asset: " +vppAssetDTOs.getAdamId();
log.error(msg);
throw new ApplicationManagementException(msg);
}
ConnectionManagerUtil.commitDBTransaction();
} catch (ApplicationManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while updating the Asset.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (TransactionManagementException e) {
String msg = "Error occurred while executing database transaction for Asset update.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (DBConnectionException e) {
String msg = "Error occurred while retrieving the database connection for Asset update.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
}
}
}
if (vppItuneAssetResponse.getCurrentPageIndex() == (vppItuneAssetResponse
.getTotalPages() - 1)) {
return;
} else {
syncAssets(vppItuneAssetResponse.getNextPageIndex());
}
}
} catch (IOException e) {
String msg = "Error while syncing VPP users with backend";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
}
}
private ItuneAppDTO lookupAsset(String packageName) throws ApplicationManagementException {
String lookupURL = LOOKUP_API + packageName + LOOKUP_API_PREFIX;
try {
ProxyResponse proxyResponse = callVPPBackend(lookupURL, null, getVppToken(), Constants.VPP.GET);
if ((proxyResponse.getCode() == HttpStatus.SC_OK || proxyResponse.getCode() ==
HttpStatus.SC_CREATED) && proxyResponse.getData().contains(Constants.VPP.GET_APP_DATA_RESPONSE_START)) {
String responseData = proxyResponse.getData();
JsonObject responseJson = new JsonParser().parse(responseData)
.getAsJsonObject();
JsonObject results = responseJson.getAsJsonObject(Constants.ApplicationProperties.RESULTS);
JsonObject result = results.getAsJsonObject(packageName);
String iconUrl = result.getAsJsonObject(Constants.ApplicationProperties.ARTWORK)
.get(Constants.ApplicationProperties.URL).getAsString();
int lastSlashIndex = iconUrl.lastIndexOf("/");
if (lastSlashIndex != -1) {
iconUrl = iconUrl.substring(0, lastSlashIndex + 1) + Constants.VPP.REMOTE_FILE_NAME;
}
String descriptionStandard = result.getAsJsonObject(Constants.ApplicationProperties.DESCRIPTION)
.get(Constants.ApplicationProperties.STANDARD).getAsString();
if (descriptionStandard != null && !descriptionStandard.isEmpty()) {
descriptionStandard = descriptionStandard.substring(0, 199);
}
String name = result.get(Constants.ApplicationProperties.NAME).getAsString();
double price = result.getAsJsonArray(Constants.ApplicationProperties.OFFERS).get(0)
.getAsJsonObject().get(Constants.ApplicationProperties.PRICE).getAsDouble();
String version = result.getAsJsonArray(Constants.ApplicationProperties.OFFERS)
.get(0).getAsJsonObject().get(Constants.ApplicationProperties.VERSION)
.getAsJsonObject().get(Constants.ApplicationProperties.DISPLAY).getAsString();
String[] genreNames = new Gson().fromJson(result.getAsJsonArray(Constants.ApplicationProperties.GENRE_NAMES),
String[].class);
ItuneAppDTO ituneAppDTO = new ItuneAppDTO();
ituneAppDTO.setPackageName(packageName);
ituneAppDTO.setVersion(version);
ituneAppDTO.setDescription(descriptionStandard);
ituneAppDTO.setTitle(name);
if (Constants.ApplicationProperties.PRICE_ZERO.equalsIgnoreCase(String.valueOf(price))) {
ituneAppDTO.setPaymentMethod(Constants.ApplicationProperties.FREE_SUB_METHOD);
} else {
ituneAppDTO.setPaymentMethod(Constants.ApplicationProperties.PAID_SUB_METHOD);
}
ituneAppDTO.setIconURL(iconUrl);
ituneAppDTO.setCategory(genreNames[0]);
return ituneAppDTO;
}
} catch (IOException e) {
String msg = "Error while looking up the app details";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
}
return null;
}
@Override
public VppAssetDTO getAssetByAppId(int appId) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
try {
ConnectionManagerUtil.openDBConnection();
return vppApplicationDAO.getAssetByAppId(appId, tenantId);
} catch (DBConnectionException e) {
String msg = "DB Connection error occurs while getting asset related to app with app id " + appId + ".";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementDAOException e) {
String msg = "Error occurred while getting asset data related to app with app id " + appId + ".";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public boolean addAssociation(VppAssetDTO asset, List<VppUserDTO> vppUsers) throws
ApplicationManagementException {
List<VppAssociationDTO> associations = new ArrayList<>(); // To save to UEM DBs
List<String> clientUserIds = new ArrayList<>(); // Need this to send to vpp backend.
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
if (asset != null) {
for (VppUserDTO vppUserDTO : vppUsers) {
VppAssociationDTO associationDTO = VppHttpUtil.getAssociation(vppUserDTO, asset);
associations.add(associationDTO);
clientUserIds.add(vppUserDTO.getClientUserId());
}
if (associations.size() > 0) {
//TODO: Add or Update associations
try {
// Create the VPP backend payload
List<VppItuneAssetDTO> assets = new ArrayList<>();
VppItuneAssetDTO assetDTO = new VppItuneAssetDTO();
assetDTO.setAdamId(asset.getAdamId());
assetDTO.setPricingParam(asset.getPricingParam());
assets.add(assetDTO);
VppAssociateRequestWrapper vppAssociate = new VppAssociateRequestWrapper();
vppAssociate.setAssets(assets);
vppAssociate.setClientUserIds(clientUserIds);
Gson gson = new Gson();
String payload = gson.toJson(vppAssociate);
ProxyResponse proxyResponse = callVPPBackend(ASSIGNMENTS_POST, payload, getVppToken(),
Constants.VPP.POST);
if ((proxyResponse.getCode() == HttpStatus.SC_OK || proxyResponse.getCode() ==
HttpStatus.SC_CREATED) && proxyResponse.getData().contains(Constants.VPP.EVENT_ID)) {
// Create assignment does not return any useful data. Its needed to call the backend again
ProxyResponse getAssignmentResponse = callVPPBackend(ASSIGNMENTS_GET, null, getVppToken(), Constants.VPP.GET);
if ((getAssignmentResponse.getCode() == HttpStatus.SC_OK || getAssignmentResponse.getCode() ==
HttpStatus.SC_CREATED) && getAssignmentResponse.getData().contains(Constants.VPP.TOTAL_PAGES)) {
// VppAssociateResponseWrapper vppAssociateResponseWrapper = gson.fromJson
// (getAssignmentResponse.getData(), VppAssociateResponseWrapper.class);
for (VppAssociationDTO association : associations) {
VppAssociationDTO vppAssociation = getAssociation(association.getAssetId(), association.getClientId());
if (vppAssociation == null) {
try {
ConnectionManagerUtil.beginDBTransaction();
if (vppApplicationDAO.addAssociation(association, tenantId) != -1) {
ConnectionManagerUtil.commitDBTransaction();
return true;
}
ConnectionManagerUtil.rollbackDBTransaction();
return false;
} catch (ApplicationManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while adding the Assignment.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (TransactionManagementException e) {
String msg = "Error occurred while executing database transaction for adding Assignment.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (DBConnectionException e) {
String msg = "Error occurred while retrieving the database connection for adding Assignment.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
} else {
try {
ConnectionManagerUtil.beginDBTransaction();
if (vppApplicationDAO.updateAssociation(association, tenantId) == null) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Unable to update the assignment: " +association.getAssetId();
log.error(msg);
throw new ApplicationManagementException(msg);
}
ConnectionManagerUtil.commitDBTransaction();
return true;
} catch (ApplicationManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while updating the Asset.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (TransactionManagementException e) {
String msg = "Error occurred while executing database transaction for Asset update.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (DBConnectionException e) {
String msg = "Error occurred while retrieving the database connection for Asset update.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
}
}
}
} catch (IOException e) {
String msg = "Error while adding associations";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
}
}
}
return false;
}
@Override
public VppAssociationDTO getAssociation(int assetId, int userId) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
try {
ConnectionManagerUtil.openDBConnection();
return vppApplicationDAO.getAssociation(assetId, userId, tenantId);
} catch (DBConnectionException e) {
String msg = "DB Connection error occurs while getting assignment related to user of id " + userId + ".";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementDAOException e) {
String msg = "Error occurred while getting assignment data related to user of id " + userId + ".";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public ProxyResponse callVPPBackend(String url,
String payload,
String accessToken,
String method) throws IOException {
return VppHttpUtil.execute(url, payload, accessToken, method);
}
public String getVppToken() throws ApplicationManagementException {
String token = "";
MetadataManagementService meta = APIUtil.getMetadataManager();
Metadata metadata = null;
try {
metadata = meta.retrieveMetadata("DEP_META_KEY");
if (metadata != null) {
Gson g = new Gson();
DepConfig depConfigs = g.fromJson(metadata.getMetaValue(), DepConfig.class);
token = depConfigs.getVppToken();
return token;
}
}catch (MetadataManagementException e) {
String msg = "Error when retrieving metadata of vpp feature";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
}
return token;
}
public VppAssociationDTO getUserAssociation(String adamId, String emmUsername) throws ApplicationManagementException {
// Todo: Join the 3 tables and find a matching association
return null;
}
}

@ -17,24 +17,25 @@
*/
package io.entgra.device.mgt.core.application.mgt.core.internal;
import io.entgra.device.mgt.core.application.mgt.common.services.SPApplicationManager;
import io.entgra.device.mgt.core.application.mgt.core.impl.AppmDataHandlerImpl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.framework.BundleContext;
import org.osgi.service.component.ComponentContext;
import io.entgra.device.mgt.core.application.mgt.common.config.LifecycleState;
import io.entgra.device.mgt.core.application.mgt.common.services.ApplicationManager;
import io.entgra.device.mgt.core.application.mgt.common.services.ApplicationStorageManager;
import io.entgra.device.mgt.core.application.mgt.common.services.AppmDataHandler;
import io.entgra.device.mgt.core.application.mgt.common.services.ReviewManager;
import io.entgra.device.mgt.core.application.mgt.common.services.SPApplicationManager;
import io.entgra.device.mgt.core.application.mgt.common.services.SubscriptionManager;
import io.entgra.device.mgt.core.application.mgt.common.services.VPPApplicationManager;
import io.entgra.device.mgt.core.application.mgt.core.config.ConfigurationManager;
import io.entgra.device.mgt.core.application.mgt.core.dao.common.ApplicationManagementDAOFactory;
import io.entgra.device.mgt.core.application.mgt.core.impl.AppmDataHandlerImpl;
import io.entgra.device.mgt.core.application.mgt.core.lifecycle.LifecycleStateManager;
import io.entgra.device.mgt.core.application.mgt.core.task.ScheduledAppSubscriptionTaskManager;
import io.entgra.device.mgt.core.application.mgt.core.util.ApplicationManagementUtil;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.framework.BundleContext;
import org.osgi.service.component.ComponentContext;
import org.wso2.carbon.ndatasource.core.DataSourceService;
import org.wso2.carbon.ntask.core.service.TaskService;
import org.wso2.carbon.user.core.service.RealmService;
@ -116,6 +117,12 @@ public class ApplicationManagementServiceComponent {
DataHolder.getInstance().setConfigManager(configManager);
bundleContext.registerService(AppmDataHandler.class.getName(), configManager, null);
// TODO: Get the new instance from extension like others
VPPApplicationManager vppApplicationManager = ApplicationManagementUtil
.getVPPManagerInstance();
DataHolder.getInstance().setVppApplicationManager(vppApplicationManager);
bundleContext.registerService(VPPApplicationManager.class.getName(), vppApplicationManager, null);
ScheduledAppSubscriptionTaskManager taskManager = new ScheduledAppSubscriptionTaskManager();
taskManager.scheduleCleanupTask();

@ -23,6 +23,7 @@ import io.entgra.device.mgt.core.application.mgt.common.services.AppmDataHandler
import io.entgra.device.mgt.core.application.mgt.common.services.SPApplicationManager;
import io.entgra.device.mgt.core.application.mgt.common.services.ReviewManager;
import io.entgra.device.mgt.core.application.mgt.common.services.SubscriptionManager;
import io.entgra.device.mgt.core.application.mgt.common.services.VPPApplicationManager;
import io.entgra.device.mgt.core.application.mgt.core.lifecycle.LifecycleStateManager;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.ntask.core.service.TaskService;
@ -39,6 +40,8 @@ public class DataHolder {
private SPApplicationManager SPApplicationManager;
private VPPApplicationManager vppApplicationManager;
private ApplicationManager applicationManager;
private ReviewManager reviewManager;
@ -142,4 +145,12 @@ public class DataHolder {
public void setISApplicationManager(SPApplicationManager SPApplicationManager) {
this.SPApplicationManager = SPApplicationManager;
}
public VPPApplicationManager getVppApplicationManager() {
return vppApplicationManager;
}
public void setVppApplicationManager(VPPApplicationManager vppApplicationManager) {
this.vppApplicationManager = vppApplicationManager;
}
}

@ -72,6 +72,7 @@ public class APIUtil {
private static volatile SubscriptionManager subscriptionManager;
private static volatile ReviewManager reviewManager;
private static volatile AppmDataHandler appmDataHandler;
private static volatile VPPApplicationManager vppApplicationManager;
private static volatile MetadataManagementService metadataManagementService;
public static SPApplicationManager getSPApplicationManager() {
@ -114,6 +115,24 @@ public class APIUtil {
return applicationManager;
}
public static MetadataManagementService getMetadataManager() {
if (metadataManagementService == null) {
synchronized (APIUtil.class) {
if (metadataManagementService == null) {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
metadataManagementService =
(MetadataManagementService) ctx.getOSGiService(MetadataManagementService.class, null);
if (metadataManagementService == null) {
String msg = "MetadataManagement Manager service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
}
}
}
return metadataManagementService;
}
/**
* To get the ApplicationDTO Storage Manager from the osgi context.
* @return ApplicationStoreManager instance in the current osgi context.
@ -202,6 +221,29 @@ public class APIUtil {
return reviewManager;
}
public static VPPApplicationManager getVPPManager() {
try {
if (vppApplicationManager == null) {
synchronized (APIUtil.class) {
if (vppApplicationManager == null) {
vppApplicationManager = ApplicationManagementUtil.getVPPManagerInstance();
if (vppApplicationManager == null) {
String msg = "Vpp Manager service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
}
}
}
} catch (Exception e) {
String msg = "Error occurred while getting the vpp manager";
log.error(msg);
throw new IllegalStateException(msg);
}
return vppApplicationManager;
}
/**
* To get the DataHandler from the osgi context.
* @return AppmDataHandler instance in the current osgi context.
@ -426,9 +468,13 @@ public class APIUtil {
}
List<ApplicationRelease> applicationReleases = new ArrayList<>();
if (ApplicationType.PUBLIC.toString().equals(applicationDTO.getType()) && application.getCategories()
.contains("GooglePlaySyncedApp")) {
.contains(Constants.GOOGLE_PLAY_SYNCED_APP)) {
application.setAndroidEnterpriseApp(true);
}
if (ApplicationType.PUBLIC.toString().equals(applicationDTO.getType()) && application.getCategories()
.contains(Constants.ApplicationProperties.APPLE_STORE_SYNCED_APP_CATEGORY)) {
application.setExternalAppStoreApp(true);
}
for (ApplicationReleaseDTO applicationReleaseDTO : applicationDTO.getApplicationReleaseDTOs()) {
applicationReleases.add(releaseDtoToRelease(applicationReleaseDTO));
}

@ -18,15 +18,22 @@
package io.entgra.device.mgt.core.application.mgt.core.util;
import io.entgra.device.mgt.core.application.mgt.common.ApplicationArtifact;
import io.entgra.device.mgt.core.application.mgt.core.config.ConfigurationManager;
import io.entgra.device.mgt.core.application.mgt.core.config.Extension;
import io.entgra.device.mgt.core.application.mgt.core.exception.BadRequestException;
import io.entgra.device.mgt.core.device.mgt.common.Base64File;
import io.entgra.device.mgt.core.application.mgt.common.FileDataHolder;
import io.entgra.device.mgt.core.application.mgt.common.LifecycleChanger;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ItuneAppDTO;
import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException;
import io.entgra.device.mgt.core.application.mgt.common.exception.InvalidConfigurationException;
import io.entgra.device.mgt.core.application.mgt.common.exception.RequestValidatingException;
import io.entgra.device.mgt.core.application.mgt.common.response.Application;
import io.entgra.device.mgt.core.application.mgt.common.response.Category;
import io.entgra.device.mgt.core.application.mgt.common.services.ApplicationManager;
import io.entgra.device.mgt.core.application.mgt.common.services.ApplicationStorageManager;
import io.entgra.device.mgt.core.application.mgt.common.services.ReviewManager;
import io.entgra.device.mgt.core.application.mgt.common.services.SPApplicationManager;
import io.entgra.device.mgt.core.application.mgt.common.services.SubscriptionManager;
import io.entgra.device.mgt.core.application.mgt.common.services.VPPApplicationManager;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.ApplicationUpdateWrapper;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.ApplicationWrapper;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.CustomAppReleaseWrapper;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.CustomAppWrapper;
@ -35,18 +42,34 @@ import io.entgra.device.mgt.core.application.mgt.common.wrapper.PublicAppRelease
import io.entgra.device.mgt.core.application.mgt.common.wrapper.PublicAppWrapper;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.WebAppReleaseWrapper;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.WebAppWrapper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import io.entgra.device.mgt.core.application.mgt.common.exception.InvalidConfigurationException;
import io.entgra.device.mgt.core.application.mgt.common.services.ApplicationManager;
import io.entgra.device.mgt.core.application.mgt.common.services.ApplicationStorageManager;
import io.entgra.device.mgt.core.application.mgt.common.services.ReviewManager;
import io.entgra.device.mgt.core.application.mgt.common.services.SubscriptionManager;
import io.entgra.device.mgt.core.application.mgt.core.config.ConfigurationManager;
import io.entgra.device.mgt.core.application.mgt.core.config.Extension;
import io.entgra.device.mgt.core.application.mgt.core.exception.BadRequestException;
import io.entgra.device.mgt.core.application.mgt.core.impl.VppApplicationManagerImpl;
import io.entgra.device.mgt.core.application.mgt.core.lifecycle.LifecycleStateManager;
import io.entgra.device.mgt.core.device.mgt.common.Base64File;
import io.entgra.device.mgt.core.device.mgt.common.DeviceManagementConstants;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService;
import io.entgra.device.mgt.core.device.mgt.core.common.util.FileUtil;
import io.entgra.device.mgt.core.device.mgt.core.metadata.mgt.MetadataManagementServiceImpl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@ -183,6 +206,10 @@ public class ApplicationManagementUtil {
return getInstance(extension, LifecycleStateManager.class);
}
public static VPPApplicationManager getVPPManagerInstance() {
// TODO: implement as an extension
return new VppApplicationManagerImpl();
}
/**
* This is useful to delete application artifacts if any error occurred while creating release/application
* after uploading the artifacts
@ -247,4 +274,265 @@ public class ApplicationManagementUtil {
throw new InvalidConfigurationException(msg, e);
}
}
public static void persistApp(ItuneAppDTO product) throws ApplicationManagementException {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
List<Category> categories = applicationManager.getRegisteredCategories();
if (product != null && product.getVersion() != null) {
// Generate artifacts
ApplicationArtifact applicationArtifact = generateArtifacts(product);
List<String> packageNamesOfApps = new ArrayList<>();
packageNamesOfApps.add(product.getPackageName());
List<Application> existingApps = applicationManager.getApplications(packageNamesOfApps);
if (existingApps != null && existingApps.size() > 0) {
Application app = existingApps.get(0);
if (product.getPackageName().equals(app.getPackageName())) {
ApplicationUpdateWrapper applicationUpdateWrapper = generatePubAppUpdateWrapper(product, categories);
applicationManager.updateApplication(app.getId(), applicationUpdateWrapper);
PublicAppReleaseWrapper publicAppReleaseWrapper = new PublicAppReleaseWrapper();
if (app.getSubMethod()
.equalsIgnoreCase(Constants.ApplicationProperties.FREE_SUB_METHOD)) {
publicAppReleaseWrapper.setPrice(0.0);
} else {
publicAppReleaseWrapper.setPrice(1.0);
}
publicAppReleaseWrapper.setDescription(product.getDescription());
publicAppReleaseWrapper.setReleaseType("ga");
publicAppReleaseWrapper.setVersion(product.getVersion());
publicAppReleaseWrapper.setSupportedOsVersions("4.0-12.3");
applicationManager.updatePubAppRelease(app.getApplicationReleases().get(0).getUuid(),
publicAppReleaseWrapper, applicationArtifact);
return;
}
} else {
// Generate App wrapper
PublicAppWrapper publicAppWrapper = generatePubAppWrapper(product, categories);
PublicAppReleaseWrapper appReleaseWrapper = new PublicAppReleaseWrapper();
if (publicAppWrapper.getSubMethod()
.equalsIgnoreCase(Constants.ApplicationProperties.FREE_SUB_METHOD)) {
appReleaseWrapper.setPrice(0.0);
} else {
appReleaseWrapper.setPrice(1.0);
}
appReleaseWrapper.setDescription(product.getDescription());
appReleaseWrapper.setReleaseType("ga");
appReleaseWrapper.setVersion(product.getVersion());
appReleaseWrapper.setPackageName(product.getPackageName());
appReleaseWrapper.setSupportedOsVersions("4.0-12.3");
publicAppWrapper.setPublicAppReleaseWrappers(
Arrays.asList(new PublicAppReleaseWrapper[]{appReleaseWrapper}));
try {
updateImages(appReleaseWrapper, applicationArtifact.getIconName(),
applicationArtifact.getIconStream(), applicationArtifact.getScreenshots());
Application application = applicationManager.createApplication(publicAppWrapper, false);
if (application != null && (application.getApplicationReleases().get(0).getCurrentStatus() == null
|| application.getApplicationReleases().get(0).getCurrentStatus().equals("CREATED"))) {
String uuid = application.getApplicationReleases().get(0).getUuid();
LifecycleChanger lifecycleChanger = new LifecycleChanger();
lifecycleChanger.setAction("IN-REVIEW");
applicationManager.changeLifecycleState(uuid, lifecycleChanger);
lifecycleChanger.setAction("APPROVED");
applicationManager.changeLifecycleState(uuid, lifecycleChanger);
lifecycleChanger.setAction("PUBLISHED");
applicationManager.changeLifecycleState(uuid, lifecycleChanger);
}
} catch (IOException e) {
String msg = "Error while downloading images of release.";
log.error(msg);
throw new ApplicationManagementException(msg, e);
}
}
}
}
private static PublicAppWrapper generatePubAppWrapper(ItuneAppDTO product, List<Category> categories) {
PublicAppWrapper publicAppWrapper = new PublicAppWrapper();
publicAppWrapper.setName(product.getTitle());
publicAppWrapper.setDescription(product.getDescription());
publicAppWrapper.setCategories(
Collections.singletonList(Constants.ApplicationProperties.APPLE_STORE_SYNCED_APP_CATEGORY));//Default category
for (Category category : categories) {
if (product.getCategory() == null) {
List<String> pubAppCategories = new ArrayList<>();
pubAppCategories.add(Constants.ApplicationProperties.APPLE_STORE_SYNCED_APP_CATEGORY);
publicAppWrapper.setCategories(pubAppCategories);
break;
} else if (product.getCategory().equalsIgnoreCase(category.getCategoryName())) {
List<String> pubAppCategories = new ArrayList<>();
pubAppCategories.add(category.getCategoryName());
pubAppCategories.add(Constants.ApplicationProperties.APPLE_STORE_SYNCED_APP_CATEGORY);
publicAppWrapper.setCategories(pubAppCategories);
break;
}
}
if (product.getPaymentMethod().equalsIgnoreCase(Constants.ApplicationProperties.FREE_SUB_METHOD)) {
publicAppWrapper.setSubMethod(Constants.ApplicationProperties.FREE_SUB_METHOD);
} else {
publicAppWrapper.setSubMethod(Constants.ApplicationProperties.PAID_SUB_METHOD);
}
// TODO: purchase an app from app store and see how to capture the real value for price
// field.
publicAppWrapper.setPaymentCurrency("$");
publicAppWrapper.setDeviceType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS);
return publicAppWrapper;
}
private static ApplicationUpdateWrapper generatePubAppUpdateWrapper(ItuneAppDTO product, List<Category> categories) {
ApplicationUpdateWrapper applicationUpdateWrapper = new ApplicationUpdateWrapper();
applicationUpdateWrapper.setName(product.getTitle());
applicationUpdateWrapper.setDescription(product.getDescription());
applicationUpdateWrapper.setCategories(
Collections.singletonList(Constants
.ApplicationProperties.APPLE_STORE_SYNCED_APP_CATEGORY));//Default
// add the default APPLE_STORE_SYNCED_APP_CATEGORY
for (Category category : categories) {
if (product.getCategory() == null) {
List<String> pubAppCategories = new ArrayList<>();
pubAppCategories.add(Constants.ApplicationProperties.APPLE_STORE_SYNCED_APP_CATEGORY);
applicationUpdateWrapper.setCategories(pubAppCategories);
break;
} else if (product.getCategory().equalsIgnoreCase(category.getCategoryName())) {
List<String> pubAppCategories = new ArrayList<>();
pubAppCategories.add(category.getCategoryName());
pubAppCategories.add(Constants.ApplicationProperties.APPLE_STORE_SYNCED_APP_CATEGORY);
applicationUpdateWrapper.setCategories(pubAppCategories);
break;
}
}
if (product.getPaymentMethod().equalsIgnoreCase(Constants.ApplicationProperties.FREE_SUB_METHOD)) {
applicationUpdateWrapper.setSubMethod(Constants.ApplicationProperties.FREE_SUB_METHOD);
} else {
applicationUpdateWrapper.setSubMethod(Constants.ApplicationProperties.PAID_SUB_METHOD);
}
// TODO: purchase an app from Playstore and see how to capture the real value for price field.
applicationUpdateWrapper.setPaymentCurrency("$");
return applicationUpdateWrapper;
}
private static ApplicationArtifact generateArtifacts(ItuneAppDTO product) throws ApplicationManagementException {
ApplicationArtifact applicationArtifact = new ApplicationArtifact();
String prefix = product.getPackageName();
try {
String iconName = prefix + "_icon";
applicationArtifact.setIconName(iconName);
InputStream iconInputStream = getInputStream(iconName, product.getIconURL());
applicationArtifact.setIconStream(iconInputStream);
Map<String, InputStream> screenshotMap = new HashMap<>();
// TODO: look for a way to get screenshots
for (int a = 0; a < 3; a++) {
String screenshotName = product.getPackageName() + a;
InputStream screenshotInputStream = getInputStream(screenshotName, product.getIconURL());
screenshotMap.put(screenshotName, screenshotInputStream);
}
applicationArtifact.setScreenshots(screenshotMap);
return applicationArtifact;
} catch (ApplicationManagementException e) {
String msg = "Error occurred while generating Application artifact";
log.error(msg);
throw new ApplicationManagementException(msg, e);
}
}
private static InputStream getInputStream(String filename, String url) throws ApplicationManagementException {
URL website;
try {
website = new URL(url);
} catch (MalformedURLException e) {
String msg = "Error occurred while converting the url " + url;
log.error(msg);
throw new ApplicationManagementException(msg, e);
}
ReadableByteChannel rbc = null;
FileOutputStream fos = null;
try {
rbc = Channels.newChannel(website.openStream());
fos = new FileOutputStream(System.getProperty("java.io.tmpdir")
+ File.separator + filename);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
} catch (IOException e) {
String msg = "Error occurred while opening stream for url " + url;
log.error(msg);
throw new ApplicationManagementException(msg, e);
} finally {
try {
fos.close();
rbc.close();
} catch (IOException e) {
}
}
File file = new File(System.getProperty("java.io.tmpdir") + File.separator + filename);
InputStream targetStream;
try {
targetStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
String msg = "Error occurred while reading the tmp file " + System.getProperty("java.io.tmpdir")
+ File.separator + filename;
log.error(msg);
throw new ApplicationManagementException(msg, e);
}
file.deleteOnExit();
return targetStream;
}
private static void updateImages(PublicAppReleaseWrapper appReleaseWrapper, String iconName,
InputStream iconStream, Map<String, InputStream>
screenshotsMaps) throws IOException {
List<Base64File> screenshots = new ArrayList<>();
Base64File iconFile = new Base64File(iconName,
convertStreamToBase64(iconStream));
appReleaseWrapper.setIcon(iconFile);
if (screenshotsMaps.size() > 0) {
for (Map.Entry<String, InputStream> screenshotEntry : screenshotsMaps.entrySet()) {
Base64File screenshot = new Base64File(screenshotEntry.getKey(),
convertStreamToBase64(screenshotEntry.getValue()));
screenshots.add(screenshot);
}
appReleaseWrapper.setScreenshots(screenshots);
}
}
private static String convertStreamToBase64(InputStream inputStream) throws IOException {
final int bufLen = 4 * 0x400; // 4KB
byte[] buf = new byte[bufLen];
int readLen;
try {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
while ((readLen = inputStream.read(buf, 0, bufLen)) != -1)
outputStream.write(buf, 0, readLen);
return Base64.getEncoder().encodeToString(outputStream.toByteArray());
}
} catch (IOException e) {
String msg = "Error while converting image to base64";
log.error(msg);
throw e;
} finally {
try {
inputStream.close();
} catch (IOException e) {
}
}
}
public static List<Application> getAppDetails(String adamId) throws ApplicationManagementException {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
List<String> packageNamesOfApps = new ArrayList<>();
packageNamesOfApps.add(adamId);
return applicationManager.getApplications(packageNamesOfApps);
}
}

@ -74,6 +74,7 @@ public class Constants {
public static final String IS_USER_ABLE_TO_VIEW_ALL_ROLES = "isUserAbleToViewAllRoles";
public static final String GOOGLE_PLAY_STORE_URL = "https://play.google.com/store/apps/details?id=";
public static final String APPLE_STORE_URL = "https://itunes.apple.com/country/app/app-name/id";
public static final String GOOGLE_PLAY_SYNCED_APP = "GooglePlaySyncedApp";
// Subscription task related constants
public static final String SUBSCRIBERS = "SUBSCRIBERS";
@ -101,6 +102,25 @@ public class Constants {
}
public static final Map<String, String> AGENT_FILE_NAMES = Collections.unmodifiableMap(AGENT_DATA);
public static final class VPP {
public static final String GET = "GET";
public static final String BEARER = "Bearer ";
public static final String EXECUTOR_EXCEPTION_PREFIX = "ExecutorException-";
public static final String TOKEN_IS_EXPIRED = "ACCESS_TOKEN_IS_EXPIRED";
public static final int INTERNAL_ERROR_CODE = 500;
public static final String POST = "POST";
public static final String PUT = "PUT";
public static final String DELETE = "DELETE";
public static final String EVENT_ID = "eventId";
public static final String CLIENT_USER_ID_PARAM = "?clientUserId=";
public static final String TOTAL_PAGES = "totalPages";
public static final String GET_APP_DATA_RESPONSE_START = "results";
public static final String REMOTE_FILE_NAME = "512x512w.png";
private VPP() {
}
}
/**
* Database types supported by Application Management.
@ -165,4 +185,31 @@ public class Constants {
public static final String AUTHORIZATION = "Authorization";
public static final String AUTHORIZATION_HEADER_VALUE = "Bearer ";
}
public final class ApplicationProperties {
private ApplicationProperties() {
throw new AssertionError();
}
public static final String NAME = "name";
public static final String VERSION = "version";
public static final String FREE_SUB_METHOD = "FREE";
public static final String PAID_SUB_METHOD = "PAID";
public static final String TYPE = "type";;
public static final String PACKAGE_NAME = "packageName";
public static final String APPLE_STORE_SYNCED_APP_CATEGORY = "AppleStoreSyncedApp";
public static final String RESULTS = "results";
public static final String ARTWORK = "artwork";
public static final String URL = "url";
public static final String DESCRIPTION = "description";
public static final String STANDARD = "standard";
public static final String OFFERS = "offers";
public static final String PRICE = "price";
public static final String DISPLAY = "display";
public static final String GENRE_NAMES = "genreNames";
public static final String PRICE_ZERO = "0.0";
public static final String ASSOCIATION_DEVICE = "ASSOCIATION_DEVICE";
public static final String ASSOCIATION_USER = "ASSOCIATION_USER";
}
}

@ -19,30 +19,28 @@ package io.entgra.device.mgt.core.application.mgt.core.util;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import io.entgra.device.mgt.core.application.mgt.common.dto.IdentityServerDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.*;
import io.entgra.device.mgt.core.application.mgt.core.exception.UnexpectedServerErrorException;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Activity;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionType;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ReviewDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO;
import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Date;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@ -241,6 +239,26 @@ public class DAOUtil {
return applicationDTOs.get(0);
}
public static ApplicationDTO loadDeviceApp(ResultSet rs) throws SQLException {
ApplicationDTO application = new ApplicationDTO();
application.setId( rs.getInt("APP_ID"));
application.setName(rs.getString("APP_NAME"));
application.setDescription(rs.getString("APP_DESCRIPTION"));
application.setType(rs.getString("APP_TYPE"));
application.setSubType(rs.getString("APP_SUB_TYPE"));
application.setPaymentCurrency(rs.getString("APP_CURRENCY"));
application.setStatus(rs.getString("APP_STATUS"));
application.setAppRating(rs.getDouble("APP_RATING"));
application.setDeviceTypeId(rs.getInt("APP_DEVICE_TYPE_ID"));
ApplicationReleaseDTO releaseDTO = constructAppReleaseDTO(rs);
List<ApplicationReleaseDTO> releaseDtoList = new ArrayList<>();
if (releaseDTO != null) {
releaseDtoList.add(constructAppReleaseDTO(rs));
application.setApplicationReleaseDTOs(releaseDtoList);
}
return application;
}
/**
* Populates {@link ApplicationReleaseDTO} object with the result obtained from the database.
*
@ -344,6 +362,185 @@ public class DAOUtil {
return subscriptionDTOS;
}
public static Activity loadOperationActivity(ResultSet rs) throws SQLException, UnexpectedServerErrorException {
List<Activity> activity = loadOperationActivities(rs);
if (activity.isEmpty()) {
return null;
}
if (activity.size() > 1) {
String msg = "Internal server error. Found more than one app for operation";
log.error(msg);
throw new UnexpectedServerErrorException(msg);
}
return activity.get(0);
}
public static List<Activity> loadOperationActivities (ResultSet rs) throws SQLException {
List<Activity> activities = new ArrayList<>();
while (rs.next()) {
Activity activity = new Activity();
activity.setAppName(rs.getString("NAME"));
activity.setAppType(rs.getString("TYPE"));
activity.setUsername(rs.getString("SUBSCRIBED_BY"));
activity.setPackageName(rs.getString("PACKAGE_NAME"));
activity.setStatus(rs.getString("STATUS"));
activity.setVersion(rs.getString("VERSION"));
activity.setTriggeredBy(rs.getString("ACTION_TRIGGERED_FROM"));
activities.add(activity);
}
return activities;
}
public static VppUserDTO loadVppUser(ResultSet rs) throws SQLException, UnexpectedServerErrorException {
List<VppUserDTO> vppUserDTOS = loadVppUsers(rs);
if (vppUserDTOS.isEmpty()) {
return null;
}
if (vppUserDTOS.size() > 1) {
String msg = "Internal server error. Found more than one vpp user for requested emmUsername";
log.error(msg);
throw new UnexpectedServerErrorException(msg);
}
return vppUserDTOS.get(0);
}
public static List<VppUserDTO> loadVppUsers (ResultSet rs) throws SQLException {
List<VppUserDTO> vppUserDTOS = new ArrayList<>();
while (rs.next()) {
VppUserDTO vppUserDTO = new VppUserDTO();
vppUserDTO.setId(rs.getInt("ID"));
vppUserDTO.setClientUserId(rs.getString("CLIENT_USER_ID"));
vppUserDTO.setTenantId(rs.getInt("TENANT_ID"));
vppUserDTO.setEmail(rs.getString("EMAIL"));
vppUserDTO.setInviteCode(rs.getString("INVITE_CODE"));
if (columnExist(rs,"STATUS")) {
vppUserDTO.setStatus(rs.getString("STATUS"));
}
if (columnExist(rs,"MANAGED_ID")) {
vppUserDTO.setManagedId(rs.getString("MANAGED_ID"));
}
if (columnExist(rs,"TEMP_PASSWORD")) {
vppUserDTO.setTmpPassword(rs.getString("TEMP_PASSWORD"));
}
if (columnExist(rs,"DM_USERNAME")) {
vppUserDTO.setDmUsername(rs.getString("DM_USERNAME"));
}
if (rs.getLong("CREATED_TIME") != 0) {
Date date = new Date(rs.getLong("CREATED_TIME"));
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = dateFormat.format(date);
vppUserDTO.setCreatedTime(dateString);
}
if (rs.getLong("LAST_UPDATED_TIME") != 0) {
Date date = new Date(rs.getLong("LAST_UPDATED_TIME"));
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = dateFormat.format(date);
vppUserDTO.setLastUpdatedTime(dateString);
}
vppUserDTOS.add(vppUserDTO);
}
return vppUserDTOS;
}
private static boolean columnExist(ResultSet rs, String column){
try{
rs.findColumn(column);
return true;
} catch (SQLException sqlex){
}
return false;
}
public static VppAssetDTO loadAsset(ResultSet rs) throws SQLException, UnexpectedServerErrorException {
List<VppAssetDTO> vppAssetDTOS = loadAssets(rs);
if (vppAssetDTOS.isEmpty()) {
return null;
}
if (vppAssetDTOS.size() > 1) {
String msg = "Internal server error. Found more than one asset for given app id.";
log.error(msg);
throw new UnexpectedServerErrorException(msg);
}
return vppAssetDTOS.get(0);
}
public static List<VppAssetDTO> loadAssets (ResultSet rs) throws SQLException {
List<VppAssetDTO> vppAssetDTOS = new ArrayList<>();
while (rs.next()) {
VppAssetDTO vppAssetDTO = new VppAssetDTO();
vppAssetDTO.setId(rs.getInt("ID"));
vppAssetDTO.setAppId(rs.getInt("APP_ID"));
vppAssetDTO.setTenantId(rs.getInt("TENANT_ID"));
if (rs.getLong("CREATED_TIME") != 0) {
Date date = new Date(rs.getLong("CREATED_TIME"));
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = dateFormat.format(date);
vppAssetDTO.setCreatedTime(dateString);
}
if (rs.getLong("LAST_UPDATED_TIME") != 0) {
Date date = new Date(rs.getLong("LAST_UPDATED_TIME"));
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = dateFormat.format(date);
vppAssetDTO.setLastUpdatedTime(dateString);
}
vppAssetDTO.setAdamId(rs.getString("ADAM_ID"));
vppAssetDTO.setAssignedCount(rs.getString("ASSIGNED_COUNT"));
vppAssetDTO.setDeviceAssignable(rs.getString("DEVICE_ASSIGNABLE"));
vppAssetDTO.setPricingParam(rs.getString("PRICING_PARAMS"));
vppAssetDTO.setProductType(rs.getString("PRODUCT_TYPE"));
vppAssetDTO.setRetiredCount(rs.getString("RETIRED_COUNT"));
vppAssetDTO.setRevocable(rs.getString("REVOCABLE"));
// String jsonString = rs.getString("SUPPORTED_PLATFORMS");
// ObjectMapper objectMapper = new ObjectMapper();
// try {
// List<String> platformList = objectMapper.readValue(jsonString, new TypeReference<List<String>>() {});
// vppAssetDTO.setSupportedPlatforms(platformList);
// } catch (IOException e) {
// e.printStackTrace();
// }
vppAssetDTOS.add(vppAssetDTO);
}
return vppAssetDTOS;
}
public static VppAssociationDTO loadAssignment(ResultSet rs) throws SQLException, UnexpectedServerErrorException {
List<VppAssociationDTO> vppAssociationDTOS = loadAssignments(rs);
if (vppAssociationDTOS.isEmpty()) {
return null;
}
if (vppAssociationDTOS.size() > 1) {
String msg = "Internal server error. Found more than one asset for given app id.";
log.error(msg);
throw new UnexpectedServerErrorException(msg);
}
return vppAssociationDTOS.get(0);
}
public static List<VppAssociationDTO> loadAssignments (ResultSet rs) throws SQLException {
List<VppAssociationDTO> vppAssociationDTOS = new ArrayList<>();
while (rs.next()) {
VppAssociationDTO vppAssociationDTO = new VppAssociationDTO();
vppAssociationDTO.setId(rs.getInt("ID"));
vppAssociationDTO.setAssociationType(rs.getString("ASSOCIATION_TYPE"));
if (rs.getLong("CREATED_TIME") != 0) {
Date date = new Date(rs.getLong("CREATED_TIME"));
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = dateFormat.format(date);
vppAssociationDTO.setCreatedTime(dateString);
}
if (rs.getLong("LAST_UPDATED_TIME") != 0) {
Date date = new Date(rs.getLong("LAST_UPDATED_TIME"));
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = dateFormat.format(date);
vppAssociationDTO.setLastUpdatedTime(dateString);
}
vppAssociationDTO.setPricingParam(rs.getString("PRICING_PARAMS"));
vppAssociationDTOS.add(vppAssociationDTO);
}
return vppAssociationDTOS;
}
/**
* Cleans up the statement and resultset after executing the query
*

@ -0,0 +1,305 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.core.util;
import com.google.gson.Gson;
import io.entgra.device.mgt.core.application.mgt.common.dto.ProxyResponse;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppAssetDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppAssociationDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppUserDTO;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class VppHttpUtil {
private static final Log log = LogFactory.getLog(VppHttpUtil.class);
public static ProxyResponse execute(String url,
String payload,
String accessToken,
String method) throws IOException {
HttpRequestBase endpoint = null;
if (Constants.VPP.GET.equalsIgnoreCase(method) || Constants.VPP.DELETE.equalsIgnoreCase(method)) {
endpoint = new HttpGet(url);
addHeaders(endpoint, accessToken);
return VppHttpUtil.execute(endpoint);
} else if (Constants.VPP.POST.equalsIgnoreCase(method)) {
endpoint = new HttpPost(url);
} else if (Constants.VPP.PUT.equalsIgnoreCase(method)) {
endpoint = new HttpPut(url);
}
addHeaders(endpoint, accessToken);
if (payload != null) {
HttpEntity forwardRequestBody = new StringEntity(payload, ContentType.APPLICATION_JSON.toString(), "utf-8");
if (Constants.VPP.POST.equalsIgnoreCase(method)) {
((HttpPost) endpoint).setEntity(forwardRequestBody);
} else if (Constants.VPP.PUT.equalsIgnoreCase(method)) {
((HttpPut) endpoint).setEntity(forwardRequestBody);
}
}
if (log.isDebugEnabled()) {
log.info("Forwarding request to " + url);
}
return VppHttpUtil.execute(endpoint);
}
private static void addHeaders(HttpRequestBase endpoint, String accessToken) {
endpoint.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString());
endpoint.setHeader(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.toString());
endpoint.setHeader(HttpHeaders.AUTHORIZATION, Constants.VPP.BEARER + accessToken);
}
/***
*
* @param httpRequest - httpMethod e.g:- HttpPost, HttpGet
* @return response as string
* @throws IOException IO exception returns if error occurs when executing the httpMethod
*/
private static ProxyResponse execute(HttpRequestBase httpRequest) throws IOException {
try (CloseableHttpClient client = getHttpClient()) {
HttpResponse response = client.execute(httpRequest);
ProxyResponse proxyResponse = new ProxyResponse();
if (response == null) {
log.error("Received null response for http request : " + httpRequest.getMethod() + " " + httpRequest
.getURI().toString());
proxyResponse.setCode(Constants.VPP.INTERNAL_ERROR_CODE);
proxyResponse.setExecutorResponse(Constants.VPP.EXECUTOR_EXCEPTION_PREFIX + getStatusKey(
Constants.VPP.INTERNAL_ERROR_CODE));
return proxyResponse;
} else {
int statusCode = response.getStatusLine().getStatusCode();
try (BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()))) {
StringBuilder result = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
result.append(line);
}
String jsonString = result.toString();
if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_CREATED) {
proxyResponse.setCode(statusCode);
proxyResponse.setData(jsonString);
proxyResponse.setExecutorResponse("SUCCESS");
return proxyResponse;
} else if (statusCode == HttpStatus.SC_UNAUTHORIZED) {
if (jsonString.contains("Access token expired") || jsonString
.contains("Invalid input. Access token validation failed")) {
proxyResponse.setCode(statusCode);
proxyResponse.setExecutorResponse(Constants.VPP.TOKEN_IS_EXPIRED);
return proxyResponse;
} else {
log.error(
"Received " + statusCode + " response for http request : " + httpRequest.getMethod()
+ " " + httpRequest.getURI().toString() + ". Error message: " + jsonString);
proxyResponse.setCode(statusCode);
proxyResponse.setData(jsonString);
proxyResponse.setExecutorResponse(
Constants.VPP.EXECUTOR_EXCEPTION_PREFIX + getStatusKey(statusCode));
return proxyResponse;
}
}
log.error("Received " + statusCode +
" response for http request : " + httpRequest.getMethod() + " " + httpRequest.getURI()
.toString() + ". Error message: " + jsonString);
proxyResponse.setCode(statusCode);
proxyResponse.setData(jsonString);
proxyResponse
.setExecutorResponse(Constants.VPP.EXECUTOR_EXCEPTION_PREFIX + getStatusKey(statusCode));
return proxyResponse;
}
}
}
}
/***
*
* @param statusCode Provide status code, e.g:- 400, 401, 500 etc
* @return relative status code key for given status code.
*/
public static String getStatusKey(int statusCode) {
String statusCodeKey;
switch (statusCode) {
case HttpStatus.SC_INTERNAL_SERVER_ERROR:
statusCodeKey = "internalServerError";
break;
case HttpStatus.SC_BAD_REQUEST:
statusCodeKey = "badRequest";
break;
case HttpStatus.SC_UNAUTHORIZED:
statusCodeKey = "unauthorized";
break;
case HttpStatus.SC_FORBIDDEN:
statusCodeKey = "forbidden";
break;
case HttpStatus.SC_NOT_FOUND:
statusCodeKey = "notFound";
break;
case HttpStatus.SC_METHOD_NOT_ALLOWED:
statusCodeKey = "methodNotAllowed";
break;
case HttpStatus.SC_NOT_ACCEPTABLE:
statusCodeKey = "notAcceptable";
break;
case HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE:
statusCodeKey = "unsupportedMediaType";
break;
default:
statusCodeKey = "defaultPage";
break;
}
return statusCodeKey;
}
/***
* Handle error requests.
*
* @param resp {@link HttpServletResponse}
* @param proxyResponse {@link ProxyResponse}
* @throws IOException If error occurred when trying to send the error response.
*/
public static void handleError(HttpServletResponse resp, ProxyResponse proxyResponse) throws IOException {
Gson gson = new Gson();
if (proxyResponse == null) {
proxyResponse = new ProxyResponse();
proxyResponse.setCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
proxyResponse.setExecutorResponse(Constants.VPP.EXECUTOR_EXCEPTION_PREFIX + VppHttpUtil
.getStatusKey(Constants.VPP.INTERNAL_ERROR_CODE));
}
resp.setStatus(proxyResponse.getCode());
resp.setContentType(ContentType.APPLICATION_JSON.getMimeType());
resp.setCharacterEncoding(Consts.UTF_8.name());
proxyResponse.setExecutorResponse(null);
try (PrintWriter writer = resp.getWriter()) {
writer.write(gson.toJson(proxyResponse));
}
}
/**
* Handle error requests with custom error codes.
*
* @param resp {@link HttpServletResponse}
* @param errorCode HTTP error status code
* @throws IOException If error occurred when trying to send the error response.
*/
public static void handleError(HttpServletResponse resp, int errorCode)
throws IOException {
ProxyResponse proxyResponse = new ProxyResponse();
proxyResponse.setCode(errorCode);
proxyResponse.setExecutorResponse(
Constants.VPP.EXECUTOR_EXCEPTION_PREFIX + VppHttpUtil.getStatusKey(errorCode));
VppHttpUtil.handleError(resp, proxyResponse);
}
/***
*
* @param resp {@link HttpServletResponse}
* Return Success Response.
*/
public static void handleSuccess(HttpServletResponse resp, ProxyResponse proxyResponse) throws IOException {
if (proxyResponse == null) {
handleError(resp, null);
return;
}
resp.setStatus(proxyResponse.getCode());
resp.setContentType(ContentType.APPLICATION_JSON.getMimeType());
resp.setCharacterEncoding(Consts.UTF_8.name());
JSONObject response = new JSONObject();
String responseData = proxyResponse.getData();
if (!StringUtils.isEmpty(responseData)) {
try {
if (responseData.startsWith("{")) {
JSONObject responseDataJsonObj = new JSONObject(responseData);
response.put("data", responseDataJsonObj);
} else if (responseData.startsWith("[")) {
JSONArray responseDataJsonArr = new JSONArray(responseData);
response.put("data", responseDataJsonArr);
} else {
log.warn("Response data is not valid json string >> " + responseData);
response.put("data", responseData);
}
} catch (JSONException e) {
log.error("Response data is not passable");
response.put("data", responseData);
}
}
try (PrintWriter writer = resp.getWriter()) {
writer.write(response.toString());
}
}
/**
* Retrieve Http client based on hostname verification.
*
* @return {@link CloseableHttpClient} http client
*/
public static CloseableHttpClient getHttpClient() {
return HttpClients.custom().setMaxConnTotal(1).setMaxConnPerRoute(1).build();
}
public static VppAssociationDTO getAssociation(VppUserDTO user, VppAssetDTO asset) {
VppAssociationDTO associationDTO = new VppAssociationDTO();
associationDTO.setAdamId(asset.getAdamId());
associationDTO.setClientUserId(user.getClientUserId());
associationDTO.setPricingParam(asset.getPricingParam());
associationDTO.setAssociationType(Constants.ApplicationProperties.ASSOCIATION_USER);
associationDTO.setAssetId(asset.getId());
associationDTO.setClientId(user.getId());
associationDTO.setTenantId(PrivilegedCarbonContext.getThreadLocalCarbonContext()
.getTenantId(true));
associationDTO.setCreatedTime(String.valueOf(System.currentTimeMillis()));
associationDTO.setLastUpdatedTime(String.valueOf(System.currentTimeMillis()));
return associationDTO;
}
}

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>io.entgra.device.mgt.core.parent</artifactId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>certificate-mgt</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>certificate-mgt</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>certificate-mgt</artifactId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -847,8 +847,9 @@ public class CertificateGenerator {
X500Name issuerName = new X500Name(subjectDn);
String commonName = certificationRequest.getSubject().getRDNs(BCStyle.CN)[0].getFirst()
.getValue().toString();
X500Name subjectName = new X500Name("O=" + commonName + "O=AndroidDevice,CN=" +
serialNumber);
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
X500Name subjectName = new X500Name("O=" + commonName + " ,CN=" +
serialNumber + ", OU=tenant_" + tenantId);
Date startDate = new Date(System.currentTimeMillis());
Date endDate = new Date(System.currentTimeMillis()
+ TimeUnit.DAYS.toMillis(365 * 100));
@ -869,7 +870,7 @@ public class CertificateGenerator {
io.entgra.device.mgt.core.certificate.mgt.core.bean.Certificate certificate =
new io.entgra.device.mgt.core.certificate.mgt.core.bean.Certificate();
List<io.entgra.device.mgt.core.certificate.mgt.core.bean.Certificate> certificates = new ArrayList<>();
certificate.setTenantId(PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId());
certificate.setTenantId(tenantId);
certificate.setCertificate(issuedCert);
certificates.add(certificate);
saveCertInKeyStore(certificates);

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>io.entgra.device.mgt.core.parent</artifactId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>io.entgra.device.mgt.core.parent</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -308,7 +308,17 @@ public interface ActivityInfoProviderService {
"Provide the value in the Java Date Format: EEE, d MMM yyyy HH:mm:ss Z\n." +
"Example: Mon, 05 Jan 2014 15:10:00 +0200",
required = false)
@HeaderParam("If-Modified-Since") String ifModifiedSince);
@HeaderParam("If-Modified-Since") String ifModifiedSince,
@ApiParam(
name = "response",
value = "The starting pagination index for the complete list of qualified items.",
required = false)
@QueryParam("response") Boolean response,
@ApiParam(
name = "appInstall",
value = "The starting pagination index for the complete list of qualified items.",
required = false)
@QueryParam("appInstall") Boolean appInstall);
@GET
@Path("/type/{operationCode}")

@ -1760,7 +1760,6 @@ public interface DeviceManagementService {
@ApiParam(
name = "owner",
value = "Provides the owner of the required device.",
required = true,
defaultValue = "")
@QueryParam("owner")
String owner,

@ -533,7 +533,14 @@ public interface GroupManagementService {
defaultValue = "1")
@DefaultValue("1")
@QueryParam("depth")
int depth);
int depth,
@ApiParam(
name = "allowed",
value = "Whether to return allowed group",
defaultValue = "false")
@QueryParam("allowed")
@DefaultValue("false")
boolean allowed);
@Path("/name/{groupName}")
@GET

@ -18,6 +18,8 @@
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.impl;
import com.google.gson.Gson;
import io.entgra.device.mgt.core.application.mgt.common.exception.SubscriptionManagementException;
import io.entgra.device.mgt.core.application.mgt.common.services.SubscriptionManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import io.entgra.device.mgt.core.device.mgt.common.ActivityPaginationRequest;
@ -146,8 +148,11 @@ public class ActivityProviderServiceImpl implements ActivityInfoProviderService
@Size(max = 45) String devicetype,
@PathParam("deviceid")
@Size(max = 45) String deviceid,
@HeaderParam("If-Modified-Since") String ifModifiedSince) {
Activity activity;
@HeaderParam("If-Modified-Since") String ifModifiedSince,
@QueryParam("response") Boolean response,
@QueryParam("appInstall") Boolean appInstall) {
Activity activity = new Activity();
Activity appActivity = null;
DeviceManagementProviderService dmService;
try {
RequestValidationUtil.validateActivityId(id);
@ -157,7 +162,29 @@ public class ActivityProviderServiceImpl implements ActivityInfoProviderService
deviceIdentifier.setType(devicetype);
dmService = DeviceMgtAPIUtils.getDeviceManagementService();
activity = dmService.getOperationByActivityIdAndDevice(id, deviceIdentifier);
if (appInstall != null && appInstall) {
if (response != null && response) {
activity = dmService.getOperationByActivityIdAndDevice(id, deviceIdentifier);
}
SubscriptionManager subscriptionManager = DeviceMgtAPIUtils.getSubscriptionManager();
appActivity = subscriptionManager.getOperationAppDetails(id);
if (appActivity != null) {
activity.setUsername(appActivity.getUsername());
activity.setPackageName(appActivity.getPackageName());
activity.setAppName(appActivity.getAppName());
activity.setStatus(appActivity.getStatus());
activity.setAppType(appActivity.getAppType());
activity.setVersion(appActivity.getVersion());
activity.setTriggeredBy(appActivity.getTriggeredBy());
} else {
String msg = "Cannot find the app details related to the operation ";
log.error(msg);
Response.status(404).entity(msg).build();
}
} else {
activity = dmService.getOperationByActivityIdAndDevice(id, deviceIdentifier);
}
if (activity == null) {
String msg = "No activity can be " +
"found upon the provided activity id '" + id + "'";
@ -169,6 +196,11 @@ public class ActivityProviderServiceImpl implements ActivityInfoProviderService
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
} catch (SubscriptionManagementException e) {
String msg = "ErrorResponse occurred while fetching the app details for the supplied id.";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
}
}

@ -1070,10 +1070,11 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
@QueryParam("operationStatus") List<String> status) {
OperationList operationsList = new OperationList();
RequestValidationUtil requestValidationUtil = new RequestValidationUtil();
RequestValidationUtil.validateOwnerParameter(owner);
RequestValidationUtil.validatePaginationParameters(offset, limit);
PaginationRequest request = new PaginationRequest(offset, limit);
request.setOwner(owner);
if(owner != null){
request.setOwner(owner);
}
try {
//validating the operation log filters
OperationLogFilters olf = requestValidationUtil.validateOperationLogFilters(operationCode, createdFrom,

@ -176,10 +176,11 @@ public class GroupManagementServiceImpl implements GroupManagementService {
}
@Override
public Response getGroup(int groupId, boolean requireGroupProps, int depth) {
public Response getGroup(int groupId, boolean requireGroupProps, int depth, boolean allowed) {
try {
GroupManagementProviderService service = DeviceMgtAPIUtils.getGroupManagementProviderService();
DeviceGroup deviceGroup = service.getGroup(groupId, requireGroupProps, depth);
DeviceGroup deviceGroup = allowed ? service.getUserOwnGroup(groupId, requireGroupProps, depth):
service.getGroup(groupId, requireGroupProps, depth);
if (deviceGroup != null) {
return Response.status(Response.Status.OK).entity(deviceGroup).build();
} else {
@ -475,8 +476,8 @@ public class GroupManagementServiceImpl implements GroupManagementService {
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (GroupAlreadyExistException e) {
String msg = "Group already exists with name : " + groups.getName() + ".";
log.warn(msg);
String msg = "Group already exists with name : " + groups.getName() + " Try with another group name.";
log.error(msg, e);
return Response.status(Response.Status.CONFLICT).entity(msg).build();
} catch (RoleDoesNotExistException e) {
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();

@ -18,6 +18,7 @@
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.impl;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupManagementException;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata;
import org.apache.commons.logging.Log;
import org.json.simple.JSONObject;
@ -125,11 +126,14 @@ public class RoleManagementServiceImpl implements RoleManagementService {
List<String> visibleRoles;
RoleList visibleRoleList = new RoleList();
try {
metadata = DeviceMgtAPIUtils.getMetadataManagementService().retrieveMetadata(metaKey);
String metaValue = metadata.getMetaValue();
JSONParser parser = new JSONParser();
JSONObject jsonObject = (JSONObject) parser.parse(metaValue);
boolean decision = (boolean) jsonObject.get(Constants.IS_USER_ABLE_TO_VIEW_ALL_ROLES);
boolean decision = false;
if(DeviceMgtAPIUtils.getMetadataManagementService().retrieveMetadata(metaKey) != null){
metadata = DeviceMgtAPIUtils.getMetadataManagementService().retrieveMetadata(metaKey);
String metaValue = metadata.getMetaValue();
JSONParser parser = new JSONParser();
JSONObject jsonObject = (JSONObject) parser.parse(metaValue);
decision = (boolean) jsonObject.get(Constants.IS_USER_ABLE_TO_VIEW_ALL_ROLES);
}
if (decision) {
if (userStore == null || "".equals(userStore)){
userStore = PRIMARY_USER_STORE;
@ -637,6 +641,7 @@ public class RoleManagementServiceImpl implements RoleManagementService {
@Consumes(MediaType.WILDCARD)
@Override
public Response deleteRole(@PathParam("roleName") String roleName, @QueryParam("user-store") String userStoreName) {
String roleToDelete = roleName;
if (userStoreName != null && !userStoreName.isEmpty()) {
roleName = userStoreName + "/" + roleName;
}
@ -644,6 +649,7 @@ public class RoleManagementServiceImpl implements RoleManagementService {
try {
final UserRealm userRealm = DeviceMgtAPIUtils.getUserRealm();
final UserStoreManager userStoreManager = userRealm.getUserStoreManager();
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
if (!userStoreManager.isExistingRole(roleName)) {
String msg = "No role exists with the name : " + roleName ;
return Response.status(404).entity(msg).build();
@ -653,16 +659,18 @@ public class RoleManagementServiceImpl implements RoleManagementService {
if (log.isDebugEnabled()) {
log.debug("Deleting the role in user store");
}
userStoreManager.deleteRole(roleName);
// Delete all authorizations for the current role before deleting
authorizationManager.clearRoleAuthorization(roleName);
DeviceMgtAPIUtils.getGroupManagementProviderService().deleteRoleAndRoleGroupMapping(roleName, roleToDelete, tenantId, userStoreManager, authorizationManager);
return Response.status(Response.Status.OK).build();
} catch (UserStoreException e) {
String msg = "Error occurred while deleting the role '" + roleName + "'";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
} catch (GroupManagementException e) {
String msg = "Error occurred while deleting group-role mapping records";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
}
}

@ -187,8 +187,8 @@ public class GroupManagementAdminServiceImpl implements GroupManagementAdminServ
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (GroupAlreadyExistException e) {
String msg = "Group already exists with name : " + group.getName() + ".";
log.warn(msg);
String msg = "Group already exists with name : " + group.getName() + " Try with another group name.";
log.error(msg, e);
return Response.status(Response.Status.CONFLICT).entity(msg).build();
} catch (RoleDoesNotExistException e) {
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();

@ -206,7 +206,7 @@ public class ActivityProviderServiceImplTest {
Mockito.when(this.deviceManagementProviderService
.getOperationByActivityIdAndDevice(TEST_ACTIVITY_ID, deviceIdentifier)).thenReturn(activity);
Response response = this.activityInfoProviderService.getActivityByDevice(TEST_ACTIVITY_ID,
DEVICE_TYPE, DEVICE_ID, IF_MODIFIED_SINCE);
DEVICE_TYPE, DEVICE_ID, IF_MODIFIED_SINCE, false, false);
Assert.assertNotNull(response);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
Mockito.reset(this.deviceManagementProviderService);

@ -176,13 +176,13 @@ public class GroupManagementServiceImplTest {
Mockito.doReturn(new DeviceGroup()).when(groupManagementProviderService).getGroup(1, false, 1);
Mockito.doReturn(null).when(groupManagementProviderService).getGroup(2, false, 1);
Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService).getGroup(3, false, 1);
Response response = groupManagementService.getGroup(1, false, 1);
Response response = groupManagementService.getGroup(1, false, 1, false);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"getGroup request failed for a request with valid parameters");
response = groupManagementService.getGroup(2, false, 1);
response = groupManagementService.getGroup(2, false, 1, false);
Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode(),
"getGroup request returned a group for a non-existing group");
response = groupManagementService.getGroup(3, false, 1);
response = groupManagementService.getGroup(3, false, 1, false);
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"getGroup request returned a group for a in-valid request");
}

@ -21,7 +21,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -80,6 +80,32 @@ public class Activity {
@JsonProperty("initiatedBy")
private String initiatedBy;
@ApiModelProperty(name = "appName", value = "App Name.")
private String appName;
@ApiModelProperty(name = "packageName",
value = "package name of the application")
private String packageName;
@ApiModelProperty(name = "username",
value = "username of subscribed person")
private String username;
@ApiModelProperty(name = "status",
value = "Status of app install")
private String status;
@ApiModelProperty(name = "version",
value = "Version of app")
private String version;
@ApiModelProperty(name = "triggeredBy",
value = "Operation triggered by what")
private String triggeredBy;
@ApiModelProperty(name = "appType",
value = "Type of application")
private String appType;
public String getActivityId() {
return activityId;
}
@ -127,5 +153,61 @@ public class Activity {
public void setInitiatedBy(String initiatedBy) {
this.initiatedBy = initiatedBy;
}
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getTriggeredBy() {
return triggeredBy;
}
public void setTriggeredBy(String triggeredBy) {
this.triggeredBy = triggeredBy;
}
public String getAppType() {
return appType;
}
public void setAppType(String appType) {
this.appType = appType;
}
}

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.27-SNAPSHOT</version>
<version>5.0.29-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save