inoshperera 1 year ago
parent cc8470d3c0
commit 665702d504

@ -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,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,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;
}
}

@ -22,6 +22,7 @@ public class VppPaginationDTO {
int currentPageIndex; int currentPageIndex;
int size; int size;
String tokenExpirationDate; String tokenExpirationDate;
int nextPageIndex;
int totalPages; int totalPages;
String uId; String uId;
String versionId; String versionId;
@ -50,6 +51,14 @@ public class VppPaginationDTO {
this.tokenExpirationDate = tokenExpirationDate; this.tokenExpirationDate = tokenExpirationDate;
} }
public int getNextPageIndex() {
return nextPageIndex;
}
public void setNextPageIndex(int nextPageIndex) {
this.nextPageIndex = nextPageIndex;
}
public int getTotalPages() { public int getTotalPages() {
return totalPages; return totalPages;
} }

@ -19,6 +19,7 @@
package io.entgra.device.mgt.core.application.mgt.common.services; 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.ProxyResponse;
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.dto.VppUserDTO;
import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException; import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException;
@ -34,5 +35,9 @@ public interface VPPApplicationManager {
void syncUsers(String clientId) throws ApplicationManagementException; void syncUsers(String clientId) throws ApplicationManagementException;
void syncAssets(int nextPageIndex) throws ApplicationManagementException;
VppAssetDTO getAssetByAppId(String appId) throws ApplicationManagementException;
ProxyResponse callVPPBackend(String url, String payload, String accessToken, String method) throws IOException; ProxyResponse callVPPBackend(String url, String payload, String accessToken, String method) throws IOException;
} }

@ -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;
}
}

@ -18,16 +18,18 @@
package io.entgra.device.mgt.core.application.mgt.core.impl; package io.entgra.device.mgt.core.application.mgt.core.impl;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
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.ProxyResponse;
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.VppItuneUserDTO;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.VppItuneUserRequestWrapper;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppUserDTO; 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.ApplicationManagementException;
import io.entgra.device.mgt.core.application.mgt.common.services.VPPApplicationManager; import io.entgra.device.mgt.core.application.mgt.common.services.VPPApplicationManager;
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.common.wrapper.VppItuneUserResponseWrapper;
import io.entgra.device.mgt.core.application.mgt.core.dao.ApplicationDAO; 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.SPApplicationDAO;
@ -35,11 +37,13 @@ import io.entgra.device.mgt.core.application.mgt.core.dao.VisibilityDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.common.ApplicationManagementDAOFactory; import io.entgra.device.mgt.core.application.mgt.core.dao.common.ApplicationManagementDAOFactory;
import io.entgra.device.mgt.core.application.mgt.core.internal.DataHolder; 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.lifecycle.LifecycleStateManager;
import io.entgra.device.mgt.core.application.mgt.core.util.ApplicationManagementUtil;
import io.entgra.device.mgt.core.application.mgt.core.util.Constants; 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.VppHttpUtil;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpStatus; import org.apache.http.HttpStatus;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import java.io.IOException; import java.io.IOException;
@ -50,8 +54,14 @@ public class VppApplicationManagerImpl implements VPPApplicationManager {
private static final String USER_UPDATE = APP_API + "/users/update"; private static final String USER_UPDATE = APP_API + "/users/update";
private static final String USER_GET = APP_API + "/users"; private static final String USER_GET = APP_API + "/users";
private static final String TOKEN = ""; 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 static final Log log = LogFactory.getLog(VppApplicationManagerImpl.class);
private ApplicationDAO applicationDAO; private ApplicationDAO applicationDAO;
private SPApplicationDAO spApplicationDAO; private SPApplicationDAO spApplicationDAO;
private VisibilityDAO visibilityDAO; private VisibilityDAO visibilityDAO;
@ -154,6 +164,56 @@ public class VppApplicationManagerImpl implements VPPApplicationManager {
Gson gson = new Gson(); Gson gson = new Gson();
VppItuneUserResponseWrapper vppUserResponseWrapper = gson.fromJson VppItuneUserResponseWrapper vppUserResponseWrapper = gson.fromJson
(proxyResponse.getData(), VppItuneUserResponseWrapper.class); (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;
try {
String url = ASSETS;
if (nextPageIndex > 0) { // Not the first page
url += "?pageIndex=" + nextPageIndex;
}
proxyResponse = callVPPBackend(url, null, TOKEN, 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);
}
// TODO: Store/update vppItuneAssetResponse.getAssets() in the DB
// TODO: END of DAO access
}
if (vppItuneAssetResponse.getCurrentPageIndex() == (vppItuneAssetResponse
.getTotalPages() - 1)) {
return;
} else {
syncAssets(vppItuneAssetResponse.getNextPageIndex());
}
} }
} catch (IOException e) { } catch (IOException e) {
String msg = "Error while syncing VPP users with backend"; String msg = "Error while syncing VPP users with backend";
@ -161,6 +221,73 @@ public class VppApplicationManagerImpl implements VPPApplicationManager {
throw new ApplicationManagementException(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, TOKEN, 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;
}
public VppAssetDTO getAssetByAppId(String appId) throws ApplicationManagementException {
// App ID is the app id of the App management database
VppAssetDTO assetDTO = null; // TODO: load from the DB
return assetDTO;
} }
@Override @Override

@ -18,15 +18,21 @@
package io.entgra.device.mgt.core.application.mgt.core.util; 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.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.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.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.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.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.SPApplicationManager;
import io.entgra.device.mgt.core.application.mgt.common.services.SubscriptionManager;
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.ApplicationWrapper;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.CustomAppReleaseWrapper; import io.entgra.device.mgt.core.application.mgt.common.wrapper.CustomAppReleaseWrapper;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.CustomAppWrapper; import io.entgra.device.mgt.core.application.mgt.common.wrapper.CustomAppWrapper;
@ -35,18 +41,31 @@ 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.PublicAppWrapper;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.WebAppReleaseWrapper; import io.entgra.device.mgt.core.application.mgt.common.wrapper.WebAppReleaseWrapper;
import io.entgra.device.mgt.core.application.mgt.common.wrapper.WebAppWrapper; import io.entgra.device.mgt.core.application.mgt.common.wrapper.WebAppWrapper;
import org.apache.commons.logging.Log; import io.entgra.device.mgt.core.application.mgt.core.config.ConfigurationManager;
import org.apache.commons.logging.LogFactory; import io.entgra.device.mgt.core.application.mgt.core.config.Extension;
import io.entgra.device.mgt.core.application.mgt.common.exception.InvalidConfigurationException; import io.entgra.device.mgt.core.application.mgt.core.exception.BadRequestException;
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.lifecycle.LifecycleStateManager; 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.core.common.util.FileUtil; import io.entgra.device.mgt.core.device.mgt.core.common.util.FileUtil;
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.io.InputStream;
import java.lang.reflect.Constructor; 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.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -247,4 +266,258 @@ public class ApplicationManagementUtil {
throw new InvalidConfigurationException(msg, e); 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) {
}
}
}
} }

@ -109,10 +109,11 @@ public class Constants {
public static final String POST = "POST"; public static final String POST = "POST";
public static final String PUT = "PUT"; public static final String PUT = "PUT";
public static final String DELETE = "DELETE"; public static final String DELETE = "DELETE";
public static final String CLIENT_USER_ID = "clientUserId";
public static final String EVENT_ID = "eventId"; public static final String EVENT_ID = "eventId";
public static final String CLIENT_USER_ID_PARAM = "?clientUserId="; public static final String CLIENT_USER_ID_PARAM = "?clientUserId=";
public static final String TOTAL_PAGES = "totalPages"; 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() { private VPP() {
} }
@ -182,4 +183,29 @@ public class Constants {
public static final String AUTHORIZATION = "Authorization"; public static final String AUTHORIZATION = "Authorization";
public static final String AUTHORIZATION_HEADER_VALUE = "Bearer "; 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 = "APPLE_STORE_SYNCED_APP";
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";
}
} }

Loading…
Cancel
Save