Merge branch 'corrective-policy' of https://gitlab.com/entgra/carbon-device-mgt into corrective-policy

corrective-policy
Pahansith 4 years ago
commit 0f915a2961

@ -17,5 +17,5 @@
package org.wso2.carbon.device.application.mgt.common;
public enum DeviceTypes {
ANDROID, IOS
ANDROID, IOS, WINDOWS
}

@ -31,6 +31,10 @@ public class Application {
required = true)
private String name;
@ApiModelProperty(name = "installerName",
value = "Application Installer Name")
private String installerName;
@ApiModelProperty(name = "description",
value = "Description of the application",
required = true)
@ -173,4 +177,8 @@ public class Application {
public boolean isAndroidEnterpriseApp() { return isAndroidEnterpriseApp; }
public void setAndroidEnterpriseApp(boolean androidEnterpriseApp) { isAndroidEnterpriseApp = androidEnterpriseApp; }
public String getInstallerName() { return installerName; }
public void setInstallerName(String installerName) { this.installerName = installerName; }
}

@ -87,6 +87,10 @@ public class ApplicationRelease {
value = "Application Rating")
private double rating;
@ApiModelProperty(name = "packageName",
value = "package name of the application")
private String packageName;
public String getReleaseType() {
return releaseType;
}
@ -162,4 +166,8 @@ public class ApplicationRelease {
public List<String> getScreenshots() { return screenshots; }
public void setScreenshots(List<String> screenshots) { this.screenshots = screenshots; }
public String getPackageName() { return packageName; }
public void setPackageName(String packageName) { this.packageName = packageName; }
}

@ -281,6 +281,16 @@ public interface ApplicationManager {
String getInstallableLifecycleState() throws ApplicationManagementException;
/**
* Check if there are subscription devices for operations
*
* @param operationId Id of the operation
* @param deviceId deviceId of the relevant device
* @return boolean value either true or false according to the situation
* @throws ApplicationManagementException
*/
boolean checkSubDeviceIdsForOperations(int operationId, int deviceId) throws ApplicationManagementException;
void updateSubsStatus (int deviceId, int operationId, String status) throws ApplicationManagementException;

@ -60,6 +60,14 @@ public class EntAppReleaseWrapper {
@NotNull
private String supportedOsVersions;
@ApiModelProperty(name = "version",
value = "Version number of the applications installer specifically for windows")
private String version;
@ApiModelProperty(name = "packageName",
value = "PackageName of the application installer specifically for windows")
private String packageName;
public String getReleaseType() {
return releaseType;
}
@ -99,4 +107,20 @@ public class EntAppReleaseWrapper {
public String getSupportedOsVersions() { return supportedOsVersions; }
public void setSupportedOsVersions(String supportedOsVersions) { this.supportedOsVersions = supportedOsVersions; }
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
}

@ -141,6 +141,7 @@ public class ApplicationManagerImpl implements ApplicationManager {
}
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
ApplicationDTO applicationDTO = APIUtil.convertToAppDTO(applicationWrapper);
//uploading application artifacts
ApplicationReleaseDTO applicationReleaseDTO = uploadEntAppReleaseArtifacts(
applicationDTO.getApplicationReleaseDTOs().get(0), applicationArtifact,
@ -338,24 +339,36 @@ public class ApplicationManagerImpl implements ApplicationManager {
byte[] content = IOUtils.toByteArray(applicationArtifact.getInstallerStream());
applicationReleaseDTO.setInstallerName(applicationArtifact.getInstallerName());
try (ByteArrayInputStream binary = new ByteArrayInputStream(content)) {
ApplicationInstaller applicationInstaller = applicationStorageManager
.getAppInstallerData(binary, deviceType);
String packagename = applicationInstaller.getPackageName();
if (!DeviceTypes.WINDOWS.toString().equalsIgnoreCase(deviceType)) {
ApplicationInstaller applicationInstaller = applicationStorageManager
.getAppInstallerData(binary, deviceType);
applicationReleaseDTO.setVersion(applicationInstaller.getVersion());
applicationReleaseDTO.setPackageName(applicationInstaller.getPackageName());
} else {
String windowsInstallerName = applicationArtifact.getInstallerName();
String extension = windowsInstallerName.substring(windowsInstallerName.lastIndexOf(".") + 1);
if (!extension.equalsIgnoreCase(Constants.MSI) &&
!extension.equalsIgnoreCase(Constants.APPX)) {
String msg = "Application Type doesn't match with supporting application types of " +
deviceType + "platform which are APPX and MSI";
log.error(msg);
throw new BadRequestException(msg);
}
}
String packageName = applicationReleaseDTO.getPackageName();
try {
ConnectionManagerUtil.openDBConnection();
if (!isNewRelease && applicationReleaseDAO
.isActiveReleaseExisitForPackageName(packagename, tenantId,
.isActiveReleaseExisitForPackageName(packageName, tenantId,
lifecycleStateManager.getEndState())) {
String msg = "Application release is already exist for the package name: " + packagename
+ ". Either you can delete all application releases for package " + packagename + " or "
String msg = "Application release is already exist for the package name: " + packageName
+ ". Either you can delete all application releases for package " + packageName + " or "
+ "you can add this app release as an new application release, under the existing "
+ "application.";
log.error(msg);
throw new ApplicationManagementException(msg);
}
applicationReleaseDTO.setVersion(applicationInstaller.getVersion());
applicationReleaseDTO.setPackageName(packagename);
String md5OfApp = StorageManagementUtil.getMD5(new ByteArrayInputStream(content));
if (md5OfApp == null) {
String msg = "Error occurred while md5sum value retrieving process: application UUID "
@ -1012,6 +1025,7 @@ public class ApplicationManagerImpl implements ApplicationManager {
log.error(msg);
throw new BadRequestException(msg);
}
ApplicationReleaseDTO applicationReleaseDTO = uploadEntAppReleaseArtifacts(
APIUtil.releaseWrapperToReleaseDTO(entAppReleaseWrapper), applicationArtifact, deviceType.getName(),
tenantId, true);
@ -1909,13 +1923,13 @@ public class ApplicationManagerImpl implements ApplicationManager {
int deviceTypeId;
if (!deviceTypeName.equals(Constants.ALL)) {
DeviceType deviceType = deviceManagementProviderService.getDeviceType(deviceTypeName);
deviceTypeId = deviceType.getId();
if (deviceType == null) {
String msg = "Device type doesn't exist. Hence check the application name existence with valid "
+ "device type name.";
log.error(msg);
throw new BadRequestException(msg);
}
deviceTypeId = deviceType.getId();
} else {
//For web-clips device type = 'ALL'
deviceTypeId = 0;
@ -2662,6 +2676,7 @@ public class ApplicationManagerImpl implements ApplicationManager {
try {
ConnectionManagerUtil.beginDBTransaction();
ApplicationDTO applicationDTO = this.applicationDAO.getAppWithRelatedRelease(releaseUuid, tenantId);
DeviceType deviceTypeObj = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId());
AtomicReference<ApplicationReleaseDTO> applicationReleaseDTO = new AtomicReference<>(
applicationDTO.getApplicationReleaseDTOs().get(0));
validateAppReleaseUpdating(entAppReleaseWrapper, applicationDTO, applicationArtifact,
@ -2681,9 +2696,18 @@ public class ApplicationManagerImpl implements ApplicationManager {
applicationReleaseDTO.get().setMetaData(entAppReleaseWrapper.getMetaData());
}
//If the application device type is WINDOWS, it is allowed to modify version number and package name.
if (DeviceTypes.WINDOWS.toString().equalsIgnoreCase(deviceTypeObj.getName())) {
if (!StringUtils.isEmpty(entAppReleaseWrapper.getVersion())) {
applicationReleaseDTO.get().setVersion(entAppReleaseWrapper.getVersion());
}
if (!StringUtils.isEmpty(entAppReleaseWrapper.getPackageName())) {
applicationReleaseDTO.get().setPackageName(entAppReleaseWrapper.getPackageName());
}
}
if (!StringUtils.isEmpty(applicationArtifact.getInstallerName())
&& applicationArtifact.getInstallerStream() != null) {
DeviceType deviceTypeObj = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId());
applicationReleaseDTO
.set(updateEntAppReleaseArtifact(deviceTypeObj.getName(), applicationReleaseDTO.get(),
applicationArtifact));
@ -3326,6 +3350,15 @@ public class ApplicationManagerImpl implements ApplicationManager {
log.error(msg);
throw new BadRequestException(msg);
}
//Validating the version number and the packageName of the Windows new applications releases
if (DeviceTypes.WINDOWS.toString().equalsIgnoreCase(deviceType)) {
if (entAppReleaseWrapper.get().getVersion() == null || entAppReleaseWrapper.get().getPackageName() == null) {
String msg = "Application Version number or/and PackageName..both are required only when the app type is " +
deviceType + " platform type";
log.error(msg);
throw new BadRequestException(msg);
}
}
} else if (param instanceof WebAppReleaseWrapper) {
WebAppReleaseWrapper webAppReleaseWrapper = (WebAppReleaseWrapper) param;
UrlValidator urlValidator = new UrlValidator();
@ -3414,18 +3447,31 @@ public class ApplicationManagerImpl implements ApplicationManager {
}
}
@Override
public boolean checkSubDeviceIdsForOperations(int operationId, int deviceId) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
ConnectionManagerUtil.openDBConnection();
List<Integer> deviceSubIds = subscriptionDAO.getDeviceSubIdsForOperation(operationId, deviceId, tenantId);
if (deviceSubIds.isEmpty()) {
return false;
}
} catch (ApplicationManagementDAOException e) {
String msg = "Error occurred while getting the device sub ids for the operations";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
return true;
}
@Override
public void updateSubsStatus (int deviceId, int operationId, String status) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
ConnectionManagerUtil.beginDBTransaction();
List<Integer> deviceSubIds = subscriptionDAO.getDeviceSubIdsForOperation(operationId, deviceId, tenantId);
if (deviceSubIds.isEmpty()){
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Couldn't find device subscription for operation id " + operationId;
log.error(msg);
throw new ApplicationManagementException(msg);
}
if (!subscriptionDAO.updateDeviceSubStatus(deviceId, deviceSubIds, status, tenantId)){
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Didn't update an any app subscription of device for operation Id: " + operationId;

@ -82,6 +82,7 @@ import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService;
import org.wso2.carbon.device.mgt.core.util.MDMAndroidOperationUtil;
import org.wso2.carbon.device.mgt.core.util.MDMIOSOperationUtil;
import org.wso2.carbon.device.mgt.core.util.MDMWindowsOperationUtil;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.device.mgt.common.PaginationResult;
@ -1022,6 +1023,18 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
log.error(msg);
throw new ApplicationManagementException(msg);
}
} else if (DeviceTypes.WINDOWS.toString().equalsIgnoreCase(deviceType)) {
app.setType(mobileAppType);
app.setIdentifier(application.getPackageName());
app.setMetaData(application.getApplicationReleases().get(0).getMetaData());
app.setName(application.getInstallerName());
if (SubAction.INSTALL.toString().equalsIgnoreCase(action)) {
return MDMWindowsOperationUtil.createInstallAppOperation(app);
} else {
String msg = "Invalid Action is found. Action: " + action;
log.error(msg);
throw new ApplicationManagementException(msg);
}
} else {
String msg = "Invalid device type is found. Device Type: " + deviceType;
log.error(msg);

@ -304,6 +304,10 @@ public class APIUtil {
applicationReleaseDTO.setIsSharedWithAllTenants(entAppReleaseWrapper.getIsSharedWithAllTenants());
applicationReleaseDTO.setMetaData(entAppReleaseWrapper.getMetaData());
applicationReleaseDTO.setSupportedOsVersions(entAppReleaseWrapper.getSupportedOsVersions());
//Setting version number value specifically for windows type and in an instance of android and ios it will be null
applicationReleaseDTO.setVersion(entAppReleaseWrapper.getVersion());
//Setting package name value specifically for windows type and in an instance of android and ios it will be null
applicationReleaseDTO.setPackageName(entAppReleaseWrapper.getPackageName());
} else if (param instanceof WebAppReleaseWrapper){
WebAppReleaseWrapper webAppReleaseWrapper = (WebAppReleaseWrapper) param;
applicationReleaseDTO.setDescription(webAppReleaseWrapper.getDescription());
@ -358,6 +362,7 @@ public class APIUtil {
application.setTags(applicationDTO.getTags());
application.setUnrestrictedRoles(applicationDTO.getUnrestrictedRoles());
application.setRating(applicationDTO.getAppRating());
application.setInstallerName(applicationDTO.getApplicationReleaseDTOs().get(0).getInstallerName());
List<ApplicationRelease> applicationReleases = new ArrayList<>();
if (ApplicationType.PUBLIC.toString().equals(applicationDTO.getType()) && application.getCategories()
.contains("GooglePlaySyncedApp")) {
@ -384,6 +389,7 @@ public class APIUtil {
applicationRelease.setDescription(applicationReleaseDTO.getDescription());
applicationRelease.setVersion(applicationReleaseDTO.getVersion());
applicationRelease.setPackageName(applicationReleaseDTO.getPackageName());
applicationRelease.setUuid(applicationReleaseDTO.getUuid());
applicationRelease.setReleaseType(applicationReleaseDTO.getReleaseType());
applicationRelease.setPrice(applicationReleaseDTO.getPrice());

@ -65,6 +65,10 @@ public class Constants {
public static final String SUBSCRIBED = "SUBSCRIBED";
public static final String UNSUBSCRIBED = "UNSUBSCRIBED";
//App type constants related to window device type
public static final String MSI = "MSI";
public static final String APPX = "APPX";
private static final Map<String, String> AGENT_DATA = new HashMap<>();
static {
AGENT_DATA.put("android", "android-agent.apk");

@ -334,7 +334,7 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} catch (ApplicationManagementException e) {
String msg = "Error occurred while creating a costom application";
String msg = "Error occurred while creating a custom application";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (RequestValidatingException e) {
@ -373,6 +373,10 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
log.error("ApplicationDTO Creation Failed");
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
} catch (BadRequestException e) {
String msg = "Found incompatible payload with enterprise app release creating request.";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} catch (ApplicationManagementException e) {
String msg = "Error occurred while creating the application";
log.error(msg, e);
@ -716,7 +720,7 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
.changeLifecycleState(applicationUuid, lifecycleChanger);
return Response.status(Response.Status.CREATED).entity(applicationRelease).build();
} catch (BadRequestException e) {
String msg = "Request payload contains invalid data, hence veryfy the request payload.";
String msg = "Request payload contains invalid data, hence verify the request payload.";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).build();
} catch (ForbiddenException e) {
@ -1005,10 +1009,10 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
}
if (attachmentList != null && !attachmentList.isEmpty()) {
Map<String, InputStream> scrrenshotData = new TreeMap<>();
Map<String, InputStream> screenshotData = new TreeMap<>();
for (Attachment sc : attachmentList) {
dataHandler = sc.getDataHandler();
String screenshotrFileName = dataHandler.getName();
String screenshotFileName = dataHandler.getName();
InputStream screenshotStream = dataHandler.getInputStream();
if (screenshotStream == null) {
String msg =
@ -1017,16 +1021,16 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
log.error(msg);
throw new BadRequestException(msg);
}
if (screenshotrFileName == null) {
if (screenshotFileName == null) {
String msg =
"Screenshot file name retrieving is failed for one screenshot. Hence can't proceed. "
+ "Please verify the screenshots.";
log.error(msg);
throw new BadRequestException(msg);
}
scrrenshotData.put(screenshotrFileName, screenshotStream);
screenshotData.put(screenshotFileName, screenshotStream);
}
applicationArtifact.setScreenshots(scrrenshotData);
applicationArtifact.setScreenshots(screenshotData);
}
return applicationArtifact;
} catch (IOException e) {

@ -85,6 +85,12 @@
}
},
"deviceTypes": {
"mobileTypes": ["android", "ios"]
"mobileTypes": ["android", "ios", "windows"]
},
"windowsDeviceType": {
"appType": ["msi", "appx"]
},
"windowsAppxMsiKeyValueForMetaData": {
"metaKeyArray": ["Package_Url", "Dependency_Package_Url", "Certificate_Hash", "Encoded_Cert_Content", "Package_Family_Name", "Product_Id", "Content_Uri", "File_Hash"]
}
}

@ -46,6 +46,7 @@ class NewAppDetailsForm extends React.Component {
categories: [],
tags: [],
deviceTypes: [],
selectedValue: null,
fetching: false,
roleSearchValue: [],
unrestrictedRoles: [],
@ -312,12 +313,33 @@ class NewAppDetailsForm extends React.Component {
});
};
// Event handler for selecting the device type
handleSelect = event => {
this.setState({
selectedValue: event,
});
if (this.props.selectedValueHandler) {
this.props.selectedValueHandler(event);
}
};
// Event handler for selecting the windows app type
handleSelectForAppType = event => {
if (this.props.selectedAppTypeHandler) {
this.props.selectedAppTypeHandler(event);
}
};
render() {
const config = this.props.context;
// Windows installation app types
const appTypes = config.windowsDeviceType.appType;
const { formConfig } = this.props;
const {
categories,
tags,
deviceTypes,
selectedValue,
fetching,
unrestrictedRoles,
} = this.state;
@ -358,6 +380,7 @@ class NewAppDetailsForm extends React.Component {
<Select
style={{ width: '100%' }}
placeholder="select device type"
onSelect={this.handleSelect.bind(this)}
>
{deviceTypes.map(deviceType => {
return (
@ -396,6 +419,31 @@ class NewAppDetailsForm extends React.Component {
})(<Input placeholder="ex: Lorem App" />)}
</Form.Item>
{/* App Type only shown for windows device types for enterprise apps */}
{selectedValue === 'windows' &&
this.props.formConfig.installationType === 'ENTERPRISE' && (
<Form.Item {...formItemLayout} label="App Type">
{getFieldDecorator('appType', {
rules: [
{
required: true,
message: 'Please select app type',
},
],
})(
<Select
style={{ width: '100%' }}
placeholder="select application type"
onSelect={this.handleSelectForAppType}
>
{appTypes.map(appType => {
return <Option key={appType}>{appType}</Option>;
})}
</Select>,
)}
</Form.Item>
)}
{/* description*/}
<Form.Item {...formItemLayout} label="Description">
{getFieldDecorator('description', {

@ -33,6 +33,7 @@ import {
} from 'antd';
import '@babel/polyfill';
import Authorized from '../../../../../../../../components/Authorized/Authorized';
import { withConfigContext } from '../../../../../../../../components/ConfigContext';
const { Text } = Typography;
@ -59,6 +60,12 @@ function getBase64(file) {
});
}
// function for access the full name of the binary file using the installation path
function extractBinaryFileName(installationPath) {
let UploadedBinaryName = installationPath.split('/');
return UploadedBinaryName[UploadedBinaryName.length - 1];
}
class NewAppUploadForm extends React.Component {
constructor(props) {
super(props);
@ -77,6 +84,7 @@ class NewAppUploadForm extends React.Component {
osVersionsHelperText: '',
osVersionsValidateStatus: 'validating',
metaData: [],
appType: null,
};
this.lowerOsVersion = null;
this.upperOsVersion = null;
@ -93,6 +101,8 @@ class NewAppUploadForm extends React.Component {
e.preventDefault();
const { formConfig } = this.props;
const { specificElements } = formConfig;
let windowsAppTypeMetaArray = [];
let metaValue = [];
this.props.form.validateFields((err, values) => {
if (!err) {
@ -107,6 +117,19 @@ class NewAppUploadForm extends React.Component {
releaseType,
} = values;
/**
* To save the metaData value that receive from
* metaData UI In an windows app type creation
*/
if (
((this.props.formConfig.installationType === 'ENTERPRISE' &&
this.props.selectedValue === 'windows') ||
this.props.deviceType === 'windows') &&
this.state.metaData.length !== 0
) {
metaValue = [...this.state.metaData];
}
// add release data
const release = {
description: releaseDescription,
@ -116,6 +139,90 @@ class NewAppUploadForm extends React.Component {
releaseType: releaseType,
};
const data = new FormData();
const config = this.props.context;
// Accessing the Meta Key value for windows device type from the config.json file
const metaKeyValues =
config.windowsAppxMsiKeyValueForMetaData.metaKeyArray;
/*
Setting up the app type specific values to the
metaData state field and Setting up the version
and the packageName for windows type
*/
if (
(this.props.formConfig.installationType === 'ENTERPRISE' &&
this.props.selectedValue === 'windows') ||
this.props.deviceType === 'windows'
) {
// Setting up the version and packageName
release.version = values.version;
release.packageName = values.packageName;
// setting the metaData value for appx type
if (
this.props.selectedAppType === 'appx' ||
this.state.appType === 'appx'
) {
windowsAppTypeMetaArray = [
{
key: metaKeyValues[0],
value: values.packageUrl,
},
{
key: metaKeyValues[1],
value: values.dependencyPackageUrl,
},
{
key: metaKeyValues[2],
value: values.certificateHash,
},
{
key: metaKeyValues[3],
value: values.encodedCertContent,
},
{
key: metaKeyValues[4],
value: values.packageName,
},
];
windowsAppTypeMetaArray = [
...windowsAppTypeMetaArray,
...metaValue,
];
} else if (
this.props.selectedAppType === 'msi' ||
this.state.appType === 'msi'
) {
windowsAppTypeMetaArray = [
{
key: metaKeyValues[5],
value: values.productId,
},
{
key: metaKeyValues[6],
value: values.contentUri,
},
{
key: metaKeyValues[7],
value: values.fileHash,
},
];
windowsAppTypeMetaArray = [
...windowsAppTypeMetaArray,
...metaValue,
];
}
this.setState(
{
metaData: windowsAppTypeMetaArray,
},
() => {
release.metaData = JSON.stringify(this.state.metaData);
this.props.onSuccessReleaseData({ data, release });
},
);
}
if (specificElements.hasOwnProperty('version')) {
release.version = values.version;
}
@ -126,7 +233,6 @@ class NewAppUploadForm extends React.Component {
release.packageName = values.packageName;
}
const data = new FormData();
let isFormValid = true; // flag to check if this form is valid
if (
@ -187,7 +293,16 @@ class NewAppUploadForm extends React.Component {
if (specificElements.hasOwnProperty('binaryFile')) {
data.append('binaryFile', binaryFile[0].originFileObj);
}
this.props.onSuccessReleaseData({ data, release });
// Condition to check is it not an Enterprise windows app creation or release
if (
!(
this.props.selectedValue === 'windows' &&
this.props.formConfig.installationType === 'ENTERPRISE'
) &&
this.props.deviceType !== 'windows'
) {
this.props.onSuccessReleaseData({ data, release });
}
}
}
});
@ -203,13 +318,44 @@ class NewAppUploadForm extends React.Component {
icons: fileList,
});
};
handleBinaryFileChange = ({ fileList }) => {
let validity = true;
// To set the app type of windows by using the binary file in an new app release
if (this.props.formConfig.isNewRelease && fileList.length !== 0) {
let firstUploadedBinaryFileName = extractBinaryFileName(
this.props.uploadedInstalltionAppType,
);
let FirstFileExtension = firstUploadedBinaryFileName.substr(
firstUploadedBinaryFileName.lastIndexOf('.') + 1,
);
let LastFileExtension = fileList[0].name.substr(
fileList[0].name.lastIndexOf('.') + 1,
);
if (FirstFileExtension !== LastFileExtension) {
validity = false;
} else if (LastFileExtension === 'msi' || LastFileExtension === 'appx') {
this.setState({
appType: LastFileExtension,
});
}
}
if (fileList.length === 1) {
this.setState({
binaryFileHelperText: '',
});
}
this.setState({ binaryFiles: fileList });
if (validity) {
this.setState({
binaryFiles: fileList,
});
} else {
this.setState({
binaryFileHelperText: 'Upload Correct Binary File extension',
});
}
};
handleScreenshotChange = ({ fileList }) => {
@ -266,6 +412,7 @@ class NewAppUploadForm extends React.Component {
render() {
const { formConfig, supportedOsVersions } = this.props;
const { getFieldDecorator } = this.props.form;
const config = this.props.context;
const {
icons,
screenshots,
@ -399,7 +546,12 @@ class NewAppUploadForm extends React.Component {
</Text>
</Col>
</Row>
{formConfig.specificElements.hasOwnProperty('packageName') && (
{/* Package Name field for windows device type and other specific scene using it */}
{(formConfig.specificElements.hasOwnProperty('packageName') ||
(this.props.formConfig.installationType === 'ENTERPRISE' &&
this.props.selectedValue === 'windows') ||
this.props.deviceType === 'windows') && (
<Form.Item {...formItemLayout} label="Package Name">
{getFieldDecorator('packageName', {
rules: [
@ -425,7 +577,11 @@ class NewAppUploadForm extends React.Component {
</Form.Item>
)}
{formConfig.specificElements.hasOwnProperty('version') && (
{/* Version field for windows device type and other specific scene using it */}
{(formConfig.specificElements.hasOwnProperty('version') ||
(this.props.formConfig.installationType === 'ENTERPRISE' &&
this.props.selectedValue === 'windows') ||
this.props.deviceType === 'windows') && (
<Form.Item {...formItemLayout} label="Version">
{getFieldDecorator('version', {
rules: [
@ -438,6 +594,127 @@ class NewAppUploadForm extends React.Component {
</Form.Item>
)}
{/* Windows Appx App Type Fields */}
{/* For Windows appx app type only -> Package Url */}
{((this.props.formConfig.installationType === 'ENTERPRISE' &&
this.props.selectedValue === 'windows' &&
this.props.selectedAppType === 'appx') ||
this.state.appType === 'appx') && (
<Form.Item {...formItemLayout} label="Package Url">
{getFieldDecorator('packageUrl', {
rules: [
{
required: true,
message: 'Please input the package url',
},
],
})(<Input placeholder="Package Url" />)}
</Form.Item>
)}
{/* For Windows appx app type only -> Dependency Package Url */}
{((this.props.formConfig.installationType === 'ENTERPRISE' &&
this.props.selectedValue === 'windows' &&
this.props.selectedAppType === 'appx') ||
this.state.appType === 'appx') && (
<Form.Item {...formItemLayout} label="Dependency Package Url">
{getFieldDecorator('dependencyPackageUrl', {})(
<Input placeholder="Dependency Package Url" />,
)}
</Form.Item>
)}
{/* For Windows appx app type only -> Certificate Hash */}
{((this.props.formConfig.installationType === 'ENTERPRISE' &&
this.props.selectedValue === 'windows' &&
this.props.selectedAppType === 'appx') ||
this.state.appType === 'appx') && (
<Form.Item {...formItemLayout} label="Certificate Hash">
{getFieldDecorator('certificateHash', {
rules: [
{
required: true,
message: 'Please input the certificate hash',
},
],
})(<Input placeholder="Certificate Hash" />)}
</Form.Item>
)}
{/* For Windows appx app type only -> Encoded Certificate Content */}
{((this.props.formConfig.installationType === 'ENTERPRISE' &&
this.props.selectedValue === 'windows' &&
this.props.selectedAppType === 'appx') ||
this.state.appType === 'appx') && (
<Form.Item {...formItemLayout} label="Encoded Cert Content">
{getFieldDecorator('encodedCertContent', {
rules: [
{
required: true,
message: 'Give the encoded cert content',
},
],
})(
<TextArea
placeholder="Enter a encoded certificate content"
rows={5}
/>,
)}
</Form.Item>
)}
{/* Windows MSI App Type Fields */}
{/* For Windows msi app type only -> Product Id */}
{((this.props.formConfig.installationType === 'ENTERPRISE' &&
this.props.selectedValue === 'windows' &&
this.props.selectedAppType === 'msi') ||
this.state.appType === 'msi') && (
<Form.Item {...formItemLayout} label="Product Id">
{getFieldDecorator('productId', {
rules: [
{
required: true,
message: 'Please input the product id',
},
],
})(<Input placeholder="Product Id" />)}
</Form.Item>
)}
{/* For Windows msi app type only -> Content URI */}
{((this.props.formConfig.installationType === 'ENTERPRISE' &&
this.props.selectedValue === 'windows' &&
this.props.selectedAppType === 'msi') ||
this.state.appType === 'msi') && (
<Form.Item {...formItemLayout} label="Content URI">
{getFieldDecorator('contentUri', {
rules: [
{
required: true,
message: 'Please input the content uri',
},
],
})(<Input placeholder="Content Uri" />)}
</Form.Item>
)}
{/* For Windows msi app type only -> File Hash */}
{((this.props.formConfig.installationType === 'ENTERPRISE' &&
this.props.selectedValue === 'windows' &&
this.props.selectedAppType === 'msi') ||
this.state.appType === 'msi') && (
<Form.Item {...formItemLayout} label="File Hash">
{getFieldDecorator('fileHash', {
rules: [
{
required: true,
message: 'Please input the file hash',
},
],
})(<Input placeholder="File Hash" />)}
</Form.Item>
)}
<Form.Item {...formItemLayout} label="Release Type">
{getFieldDecorator('releaseType', {
rules: [
@ -547,49 +824,60 @@ class NewAppUploadForm extends React.Component {
{getFieldDecorator('meta', {})(
<div>
{metaData.map((data, index) => {
return (
<InputGroup key={index}>
<Row gutter={8}>
<Col span={5}>
<Input
placeholder="key"
value={data.key}
onChange={e => {
metaData[index].key = e.currentTarget.value;
this.setState({
metaData,
});
}}
/>
</Col>
<Col span={8}>
<Input
placeholder="value"
value={data.value}
onChange={e => {
metaData[index].value = e.currentTarget.value;
this.setState({
metaData,
});
}}
/>
</Col>
<Col span={3}>
<Button
type="dashed"
shape="circle"
icon={<MinusOutlined />}
onClick={() => {
metaData.splice(index, 1);
this.setState({
metaData,
});
}}
/>
</Col>
</Row>
</InputGroup>
);
/*
Exclude showing the values related to
windows app type variables in meta Data UI
*/
if (
!config.windowsAppxMsiKeyValueForMetaData.metaKeyArray.includes(
data.key,
)
) {
return (
<InputGroup key={index}>
<Row gutter={8}>
<Col span={5}>
<Input
placeholder="key"
value={data.key}
onChange={e => {
metaData[index].key = e.currentTarget.value;
this.setState({
metaData,
});
}}
/>
</Col>
<Col span={8}>
<Input
placeholder="value"
value={data.value}
onChange={e => {
metaData[index].value =
e.currentTarget.value;
this.setState({
metaData,
});
}}
/>
</Col>
<Col span={3}>
<Button
type="dashed"
shape="circle"
icon={<MinusOutlined />}
onClick={() => {
metaData.splice(index, 1);
this.setState({
metaData,
});
}}
/>
</Col>
</Row>
</InputGroup>
);
}
})}
<Button
type="dashed"
@ -633,4 +921,6 @@ class NewAppUploadForm extends React.Component {
}
}
export default Form.create({ name: 'app-upload-form' })(NewAppUploadForm);
export default withConfigContext(
Form.create({ name: 'app-upload-form' })(NewAppUploadForm),
);

@ -44,6 +44,8 @@ class AddNewAppFormComponent extends React.Component {
release: null,
isError: false,
deviceType: null,
selectedValue: null,
selectedAppType: null,
supportedOsVersions: [],
errorText: '',
forbiddenErrors: {
@ -157,6 +159,20 @@ class AddNewAppFormComponent extends React.Component {
});
};
// For passing the device type as the prop for other component
selectedValueHandler = selectedValue => {
this.setState({
selectedValue,
});
};
// For passing the app type as the prop for other component
selectedAppTypeHandler = selectedAppType => {
this.setState({
selectedAppType,
});
};
render() {
const {
loading,
@ -164,6 +180,8 @@ class AddNewAppFormComponent extends React.Component {
isError,
supportedOsVersions,
errorText,
selectedValue,
selectedAppType,
} = this.state;
const { formConfig } = this.props;
return (
@ -180,18 +198,21 @@ class AddNewAppFormComponent extends React.Component {
<div style={{ display: current === 0 ? 'unset' : 'none' }}>
<NewAppDetailsForm
formConfig={formConfig}
selectedValueHandler={this.selectedValueHandler}
selectedAppTypeHandler={this.selectedAppTypeHandler}
onSuccessApplicationData={this.onSuccessApplicationData}
/>
</div>
<div style={{ display: current === 1 ? 'unset' : 'none' }}>
<NewAppUploadForm
formConfig={formConfig}
selectedValue={selectedValue}
selectedAppType={selectedAppType}
supportedOsVersions={supportedOsVersions}
onSuccessReleaseData={this.onSuccessReleaseData}
onClickBackButton={this.onClickBackButton}
/>
</div>
<div style={{ display: current === 2 ? 'unset' : 'none' }}>
{!isError && (
<Result

@ -27,6 +27,7 @@ import { handleApiError } from '../../../../../../services/utils/errorHandler';
import NewAppUploadForm from '../../../AddNewApp/components/AddNewAppForm/components/NewAppUploadForm';
const formConfig = {
isNewRelease: true,
specificElements: {
binaryFile: {
required: true,
@ -127,7 +128,10 @@ class AddNewReleaseFormComponent extends React.Component {
description: 'New release was added successfully',
});
const uuid = res.data.data.uuid;
this.props.history.push('/publisher/apps/releases/' + uuid);
this.props.history.push({
pathname: '/publisher/apps/releases/' + uuid,
state: { fullAppDetails: this.props.location.state.fullAppDetails },
});
} else {
this.setState({
loading: false,
@ -160,6 +164,11 @@ class AddNewReleaseFormComponent extends React.Component {
<NewAppUploadForm
forbiddenErrors={forbiddenErrors}
formConfig={formConfig}
deviceType={this.props.deviceType}
// Takes the first upload app type installation path
uploadedInstalltionAppType={
this.props.location.state.appDetails.installerPath
}
supportedOsVersions={supportedOsVersions}
onSuccessReleaseData={this.onSuccessReleaseData}
onClickBackButton={this.onClickBackButton}

@ -702,7 +702,14 @@ class AppDetailsDrawer extends React.Component {
title="Click to view full details"
placement="topRight"
>
<Link to={'apps/releases/' + release.uuid}>
<Link
to={{
pathname: `apps/releases/${release.uuid}`,
state: {
fullAppDetails: app.applicationReleases,
},
}}
>
<Card className="release-card">
<Meta
avatar={
@ -773,7 +780,13 @@ class AppDetailsDrawer extends React.Component {
<Text>Add new release for the application</Text>
</div>
<Link
to={`/publisher/apps/${app.deviceType}/${app.id}/add-release`}
to={{
pathname: `/publisher/apps/${app.deviceType}/${app.id}/add-release`,
state: {
appDetails: app.applicationReleases[0],
fullAppDetails: app.applicationReleases,
},
}}
>
<Button htmlType="button" type="primary" size="small">
Add

@ -27,6 +27,7 @@ import {
Steps,
Alert,
Tabs,
Tooltip,
} from 'antd';
import axios from 'axios';
import ReactQuill from 'react-quill';
@ -76,6 +77,7 @@ class LifeCycle extends React.Component {
current: 0,
lifecycleSteps: [],
lifeCycleStates: [],
isPublished: false,
};
}
@ -85,9 +87,11 @@ class LifeCycle extends React.Component {
const lifecycleSteps = Object.keys(lifeCycleConfig).map(config => {
return lifeCycleConfig[config];
});
let isPublished = this.checkReleaseLifeCycleStatus();
this.setState({
current: lifeCycleConfig[this.props.currentStatus].step,
lifecycleSteps,
isPublished,
});
this.getLifeCycleHistory();
}
@ -198,6 +202,27 @@ class LifeCycle extends React.Component {
this.setState({ current });
};
/*
Function to check if the same app releases are in published
state or not and assigned a boolean value to disable
the publish button if an app release is already published
*/
checkReleaseLifeCycleStatus = () => {
if (typeof this.props.appReleases !== 'undefined') {
let appReleases = this.props.appReleases.fullAppDetails;
for (let i = 0; i < appReleases.length; i++) {
if (
this.props.uuid !== appReleases[i].uuid &&
appReleases[i].currentStatus === 'PUBLISHED'
) {
return true;
}
}
return false;
}
return false;
};
render() {
const {
currentStatus,
@ -207,6 +232,7 @@ class LifeCycle extends React.Component {
lifeCycleStates,
} = this.state;
const { lifecycle } = this.props;
const text = <span>Already an app is in publish state</span>;
let proceedingStates = [];
if (
lifecycle !== null &&
@ -247,17 +273,31 @@ class LifeCycle extends React.Component {
<p>{step.text}</p>
{proceedingStates.map(lifecycleState => {
return (
<Button
size={'small'}
style={{ marginRight: 3 }}
onClick={() =>
this.showReasonModal(lifecycleState)
}
<Tooltip
key={lifecycleState}
type={'primary'}
title={
lifecycleState === 'PUBLISHED' &&
this.state.isPublished
? text
: ''
}
>
{lifecycleState}
</Button>
<Button
size={'small'}
style={{ marginRight: 3 }}
disabled={
lifecycleState === 'PUBLISHED' &&
this.state.isPublished
}
onClick={() =>
this.showReasonModal(lifecycleState)
}
key={lifecycleState}
type={'primary'}
>
{lifecycleState}
</Button>
</Tooltip>
);
})}
</div>

@ -65,6 +65,12 @@ function getBase64(file) {
reader.onerror = error => reject(error);
});
}
// function for access the name of the binary file using the installation path
function extractBinaryFileName(installationPath) {
let UploadedBinaryName = installationPath.split('/');
let binaryFileName = UploadedBinaryName[UploadedBinaryName.length - 1];
return binaryFileName.substr(binaryFileName.lastIndexOf('.') + 1);
}
class EditReleaseModal extends React.Component {
// To add subscription type & tenancy sharing, refer https://gitlab.com/entgra/carbon-device-mgt/merge_requests/331
@ -156,7 +162,6 @@ class EditReleaseModal extends React.Component {
const { formConfig } = this.state;
const { specificElements } = formConfig;
let metaData = [];
try {
metaData = JSON.parse(release.metaData);
} catch (e) {
@ -185,26 +190,34 @@ class EditReleaseModal extends React.Component {
},
});
}
if (specificElements.hasOwnProperty('version')) {
// Showing the packageName value in the edit form UI
if (
formConfig.specificElements.hasOwnProperty('packageName') ||
(this.props.type === 'ENTERPRISE' && this.props.deviceType === 'windows')
) {
this.props.form.setFields({
version: {
value: release.version,
packageName: {
value: release.packageName,
},
});
}
if (specificElements.hasOwnProperty('url')) {
// Showing the version value in the edit form UI
if (
formConfig.specificElements.hasOwnProperty('version') ||
(this.props.type === 'ENTERPRISE' && this.props.deviceType === 'windows')
) {
this.props.form.setFields({
url: {
value: release.url,
version: {
value: release.version,
},
});
}
if (specificElements.hasOwnProperty('packageName')) {
if (specificElements.hasOwnProperty('url')) {
this.props.form.setFields({
packageName: {
value: release.packageName,
url: {
value: release.url,
},
});
}
@ -248,6 +261,10 @@ class EditReleaseModal extends React.Component {
const { formConfig } = this.state;
const { specificElements } = formConfig;
// Accessing the extension type of the current uploaded binary file
const appTypeExtension = extractBinaryFileName(
this.props.release.installerPath,
);
this.props.form.validateFields((err, values) => {
if (!err) {
@ -280,10 +297,38 @@ class EditReleaseModal extends React.Component {
data.append('binaryFile', binaryFiles[0].originFileObj);
}
if (specificElements.hasOwnProperty('version')) {
if (
specificElements.hasOwnProperty('version') ||
(this.props.type === 'ENTERPRISE' &&
this.props.deviceType === 'windows')
) {
release.version = values.version;
}
// Accessing the Meta Key value for windows device type from the config.json file
const metaKeyValues =
config.windowsAppxMsiKeyValueForMetaData.metaKeyArray;
if (
specificElements.hasOwnProperty('packageName') ||
(this.props.type === 'ENTERPRISE' &&
this.props.deviceType === 'windows')
) {
release.packageName = values.packageName;
// Setting up the packageName to the package_Family_Name key in an appx app type instance
if (appTypeExtension === config.windowsDeviceType.appType[1]) {
let metaDataArray = this.state.metaData;
let filterMetaArray = metaDataArray.filter(
obj => obj.key !== metaKeyValues[4],
);
filterMetaArray.push({
key: metaKeyValues[4],
value: values.packageName,
});
release.metaData = JSON.stringify(filterMetaArray);
}
}
if (specificElements.hasOwnProperty('url')) {
release.url = values.url;
}
@ -335,7 +380,6 @@ class EditReleaseModal extends React.Component {
message: 'Done!',
description: 'Saved!',
});
// console.log(updatedRelease);
this.props.updateRelease(updatedRelease);
}
})
@ -463,7 +507,6 @@ class EditReleaseModal extends React.Component {
)}
</Form.Item>
)}
{formConfig.specificElements.hasOwnProperty('url') && (
<Form.Item {...formItemLayout} label="URL">
{getFieldDecorator('url', {
@ -477,19 +520,6 @@ class EditReleaseModal extends React.Component {
</Form.Item>
)}
{formConfig.specificElements.hasOwnProperty('version') && (
<Form.Item {...formItemLayout} label="Version">
{getFieldDecorator('version', {
rules: [
{
required: true,
message: 'Please input the version',
},
],
})(<Input placeholder="Version" />)}
</Form.Item>
)}
<Form.Item {...formItemLayout} label="Icon">
{getFieldDecorator('icon', {
valuePropName: 'icon',
@ -528,6 +558,38 @@ class EditReleaseModal extends React.Component {
)}
</Form.Item>
{/* Package Name field for windows device type and other specific scene using it */}
{(formConfig.specificElements.hasOwnProperty('packageName') ||
(this.props.type === 'ENTERPRISE' &&
this.props.deviceType === 'windows')) && (
<Form.Item {...formItemLayout} label="Package Name">
{getFieldDecorator('packageName', {
rules: [
{
required: true,
message: 'Please input the package name',
},
],
})(<Input placeholder="Package Name" />)}
</Form.Item>
)}
{/* Version field for windows device type and other specific scene using it */}
{(formConfig.specificElements.hasOwnProperty('version') ||
(this.props.type === 'ENTERPRISE' &&
this.props.deviceType === 'windows')) && (
<Form.Item {...formItemLayout} label="Version">
{getFieldDecorator('version', {
rules: [
{
required: true,
message: 'Please input the version',
},
],
})(<Input placeholder="Version" />)}
</Form.Item>
)}
<Form.Item {...formItemLayout} label="Release Type">
{getFieldDecorator('releaseType', {
rules: [
@ -650,50 +712,59 @@ class EditReleaseModal extends React.Component {
})(
<div>
{metaData.map((data, index) => {
return (
<InputGroup key={index}>
<Row gutter={8}>
<Col span={10}>
<Input
placeholder="key"
value={data.key}
onChange={e => {
metaData[index].key = e.currentTarget.value;
this.setState({
metaData,
});
}}
/>
</Col>
<Col span={10}>
<Input
placeholder="value"
value={data.value}
onChange={e => {
metaData[index].value =
e.currentTarget.value;
this.setState({
metaData,
});
}}
/>
</Col>
<Col span={3}>
<Button
type="dashed"
shape="circle"
icon={<MinusOutlined />}
onClick={() => {
metaData.splice(index, 1);
this.setState({
metaData,
});
}}
/>
</Col>
</Row>
</InputGroup>
);
if (
!(
data.key ===
config.windowsAppxMsiKeyValueForMetaData
.metaKeyArray[4]
)
) {
return (
<InputGroup key={index}>
<Row gutter={8}>
<Col span={10}>
<Input
placeholder="key"
value={data.key}
onChange={e => {
metaData[index].key =
e.currentTarget.value;
this.setState({
metaData,
});
}}
/>
</Col>
<Col span={10}>
<Input
placeholder="value"
value={data.value}
onChange={e => {
metaData[index].value =
e.currentTarget.value;
this.setState({
metaData,
});
}}
/>
</Col>
<Col span={3}>
<Button
type="dashed"
shape="circle"
icon={<MinusOutlined />}
onClick={() => {
metaData.splice(index, 1);
this.setState({
metaData,
});
}}
/>
</Col>
</Row>
</InputGroup>
);
}
})}
<Button
type="dashed"

@ -41,6 +41,8 @@ class ReleaseView extends React.Component {
const { app, release } = this.props;
const config = this.props.context;
const { lifecycle, currentLifecycleStatus } = this.props;
let isKeyInclude = false;
let metaArrayWithOutWindowsKey = [];
if (release == null) {
return null;
}
@ -169,21 +171,31 @@ class ReleaseView extends React.Component {
<Text>META DATA</Text>
<Row>
{metaData.map((data, index) => {
return (
<Col
key={index}
lg={8}
md={6}
xs={24}
style={{ marginTop: 15 }}
>
<Text>{data.key}</Text>
<br />
<Text type="secondary">{data.value}</Text>
</Col>
);
// Exclude showing the values related to windows app type variables in the metaData UI
if (
!config.windowsAppxMsiKeyValueForMetaData.metaKeyArray.includes(
data.key,
)
) {
isKeyInclude = false;
metaArrayWithOutWindowsKey.push(data);
return (
<Col
key={index}
lg={8}
md={6}
xs={24}
style={{ marginTop: 15 }}
>
<Text>{data.key}</Text>
<br />
<Text type="secondary">{data.value}</Text>
</Col>
);
}
})}
{metaData.length === 0 && (
{(metaData.length === 0 ||
(!isKeyInclude && metaArrayWithOutWindowsKey.length === 0)) && (
<Text type="secondary">No meta data available.</Text>
)}
</Row>

@ -232,6 +232,7 @@ class Release extends React.Component {
this.changeCurrentLifecycleStatus
}
lifecycle={lifecycle}
appReleases={this.props.location.state}
/>
)}
</Skeleton>

@ -40,5 +40,8 @@
"color": "#008cc4",
"theme": "filled"
}
},
"windowsAppxMsiKeyValueForMetaData": {
"metaKeyArray": ["Package_Url", "Dependency_Package_Url", "Certificate_Hash", "Encoded_Cert_Content", "Package_Family_Name", "Product_Id", "Content_Uri", "File_Hash"]
}
}

@ -148,12 +148,14 @@ class ReleaseView extends React.Component {
const config = this.props.context;
const release = app.applicationReleases[0];
let isKeyInclude = false;
let metaArrayWithOutWindowsKey = [];
let metaData = [];
try {
metaData = JSON.parse(release.metaData);
// eslint-disable-next-line no-empty
} catch (e) {}
if (app.hasOwnProperty('packageName')) {
if (app.type !== 'WEB_CLIP' && app.hasOwnProperty('packageName')) {
metaData.push({
key: 'Package Name',
value: app.packageName,
@ -270,24 +272,33 @@ class ReleaseView extends React.Component {
</div>
<Divider />
<Text>META DATA</Text>
<Row>
{metaData.map((data, index) => {
return (
<Col
key={index}
lg={8}
md={6}
xs={24}
style={{ marginTop: 15 }}
>
<Text>{data.key}</Text>
<br />
<Text type="secondary">{data.value}</Text>
</Col>
);
if (
!config.windowsAppxMsiKeyValueForMetaData.metaKeyArray.includes(
data.key,
)
) {
isKeyInclude = false;
metaArrayWithOutWindowsKey.push(data);
return (
<Col
key={index}
lg={8}
md={6}
xs={24}
style={{ marginTop: 15 }}
>
<Text>{data.key}</Text>
<br />
<Text type="secondary">{data.value}</Text>
</Col>
);
}
})}
{metaData.length === 0 && (
{(metaData.length === 0 ||
(!isKeyInclude &&
metaArrayWithOutWindowsKey.length === 0)) && (
<Text type="secondary">No meta data available.</Text>
)}
</Row>

@ -1588,8 +1588,38 @@ public interface DeviceManagementService {
@ApiParam(
name = "ownership",
value = "Provides the ownership of the required device.")
@QueryParam("owner")
String ownership);
@QueryParam("ownership")
String ownership,
@ApiParam(
name = "createdFrom",
value = "Since when user wants to filter operation logs using the created data and time")
@QueryParam("createdFrom")
Long createdFrom,
@ApiParam(
name = "createdTo",
value = "Till when user wants to filter operation logs using the created data and time")
@QueryParam("createdTo")
Long createdTo,
@ApiParam(
name = "updatedFrom",
value = "Since when user wants to filter operation logs using the received date and time")
@QueryParam("updatedFrom")
Long updatedFrom,
@ApiParam(
name = "updatedTo",
value = "Till when user wants to filter operation logs using the received date and time")
@QueryParam("updatedTo")
Long updatedTo,
@ApiParam(
name = "operationCode",
value = "Provides the operation codes to filter the operation logs via operation codes")
@QueryParam("operationCode")
List<String> operationCode,
@ApiParam(
name = "operationStatus",
value = "Provides the status codes to filter operation logs via status")
@QueryParam("operationStatus")
List<String> status);
@GET
@Produces(MediaType.APPLICATION_JSON)

@ -42,14 +42,15 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult;
import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.FeatureManager;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.OperationLogFilters;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.DeviceFilters;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.FeatureManager;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult;
import org.wso2.carbon.device.mgt.common.app.mgt.Application;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
@ -92,9 +93,9 @@ import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceList;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.beans.OperationList;
import org.wso2.carbon.device.mgt.jaxrs.beans.OperationRequest;
import org.wso2.carbon.device.mgt.jaxrs.beans.ComplianceDeviceList;
import org.wso2.carbon.device.mgt.jaxrs.beans.ApplicationList;
import org.wso2.carbon.device.mgt.jaxrs.beans.OperationStatusBean;
import org.wso2.carbon.device.mgt.jaxrs.beans.ComplianceDeviceList;
import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceManagementService;
import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.InputValidationException;
import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil;
@ -122,9 +123,9 @@ import javax.ws.rs.DefaultValue;
import javax.ws.rs.core.Response;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
@Path("/devices")
public class DeviceManagementServiceImpl implements DeviceManagementService {
@ -886,21 +887,30 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
@QueryParam("offset") int offset,
@QueryParam("limit") int limit,
@QueryParam("owner") String owner,
@QueryParam("ownership") String ownership) {
@QueryParam("ownership") String ownership,
@QueryParam("createdFrom") Long createdFrom,
@QueryParam("createdTo") Long createdTo,
@QueryParam("updatedFrom") Long updatedFrom,
@QueryParam("updatedTo") Long updatedTo,
@QueryParam("operationCode") List<String> operationCode,
@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);
PaginationResult result;
DeviceManagementProviderService dms;
try {
//validating the operation log filters
OperationLogFilters olf = requestValidationUtil.validateOperationLogFilters(operationCode, createdFrom,
createdTo, updatedFrom, updatedTo, status, type);
request.setOperationLogFilters(olf);
RequestValidationUtil.validateDeviceIdentifier(type, id);
dms = DeviceMgtAPIUtils.getDeviceManagementService();
DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService();
if (!StringUtils.isBlank(ownership)) {
request.setOwnership(ownership);
}
result = dms.getOperations(new DeviceIdentifier(id, type), request);
PaginationResult result = dms.getOperations(new DeviceIdentifier(id, type), request);
operationsList.setList((List<? extends Operation>) result.getData());
operationsList.setCount(result.getRecordsTotal());
return Response.status(Response.Status.OK).entity(operationsList).build();
@ -910,6 +920,20 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
} catch (InputValidationException e) {
String msg = "Error occurred while fetching the operations for the '" + type + "' device, which " +
"carries the id '" + id + "'";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} catch (DeviceManagementException e) {
String msg = "Error occurred while retrieving the list of [" + type + "] features with params " +
"{featureType: operation, hidden: true}";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} catch (DeviceTypeNotFoundException e) {
String msg = "No device type found with name '" + type + "'";
log.error(msg, e);
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
}
}

@ -659,7 +659,7 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService {
@QueryParam("name") String name) {
try {
GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService();
if (offset != 0 && limit != 0) {
if (offset >= 0 && limit != 0) {
PaginationRequest request = new PaginationRequest(offset, limit);
if (name != null && !name.isEmpty()) {
request.setProperty(DeviceManagementConstants.GeoServices.FENCE_NAME, name);

@ -136,6 +136,14 @@ public class PolicyManagementServiceImpl implements PolicyManagementService {
}
}
/**
* GEt {@link Policy} from {@link PolicyWrapper}
*
* @param policyWrapper {@link PolicyWrapper}
* @return {@link Policy}
* @throws DeviceManagementException if error occurred while creating {@link Policy} object from
* {@link PolicyWrapper}
*/
private Policy getPolicyFromWrapper(@Valid PolicyWrapper policyWrapper) throws DeviceManagementException {
Policy policy = new Policy();
policy.setPolicyName(policyWrapper.getPolicyName());
@ -151,7 +159,7 @@ public class PolicyManagementServiceImpl implements PolicyManagementService {
policy.setPolicyPayloadVersion(policyWrapper.getPayloadVersion());
policy.setCorrectiveActions(policyWrapper.getCorrectiveActions());
//TODO iterates the device identifiers to create the object. need to implement a proper DAO layer here.
List<Device> devices = new ArrayList<Device>();
List<Device> devices = new ArrayList<>();
List<DeviceIdentifier> deviceIdentifiers = policyWrapper.getDeviceIdentifiers();
if (deviceIdentifiers != null) {
for (DeviceIdentifier id : deviceIdentifiers) {

@ -23,11 +23,16 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpStatus;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.FeatureManager;
import org.wso2.carbon.device.mgt.common.OperationLogFilters;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceTypeNotFoundException;
import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata;
import org.wso2.carbon.device.mgt.common.notification.mgt.Notification;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.jaxrs.beans.ApplicationWrapper;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.beans.GeofenceWrapper;
@ -36,20 +41,24 @@ import org.wso2.carbon.device.mgt.jaxrs.beans.PolicyWrapper;
import org.wso2.carbon.device.mgt.jaxrs.beans.ProfileFeature;
import org.wso2.carbon.device.mgt.jaxrs.beans.RoleInfo;
import org.wso2.carbon.device.mgt.jaxrs.beans.Scope;
import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceTypeManagementService;
import org.wso2.carbon.device.mgt.jaxrs.util.Constants;
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
import org.wso2.carbon.policy.mgt.common.PolicyPayloadValidator;
import javax.ws.rs.core.Response;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class RequestValidationUtil {
private static final Log log = LogFactory.getLog(RequestValidationUtil.class);
/**
* Checks if multiple criteria are specified in a conditional request.
*
@ -477,6 +486,155 @@ public class RequestValidationUtil {
}
}
/**
* Checks if operation log filters are valid
*
* @param type Device type upon which the selection is done
* @param createdFrom Since when created date and time upon to filter operation logs
* @param createdTo Till when created date and time upon to filter operation logs
* @param updatedFrom Since when received date and time upon to filter operation logs
* @param updatedTo Till when received date and time upon to filter operation logs
* @param status List of operation status codes upon to filter operation logs
*/
public OperationLogFilters validateOperationLogFilters(List<String> operationCode,
Long createdFrom, Long createdTo, Long updatedFrom,
Long updatedTo, List<String> status, String type)
throws DeviceTypeNotFoundException, DeviceManagementException {
OperationLogFilters operationLogFilters = new OperationLogFilters();
Calendar date = Calendar.getInstance();
long timeMilli = date.getTimeInMillis();
if (updatedFrom != null || updatedTo != null) {
validateDates(updatedFrom, updatedTo);
//if user only sends the fromDate toDate sets as current date
if (updatedFrom != null && updatedTo == null) {
timeMilli = timeMilli / 1000;
operationLogFilters.setUpdatedDayTo(timeMilli);
operationLogFilters.setUpdatedDayFrom(updatedFrom);
} else {
operationLogFilters.setUpdatedDayFrom(updatedFrom);
operationLogFilters.setUpdatedDayTo(updatedTo);
}
}
if (createdTo != null || createdFrom != null) {
validateDates(createdFrom, createdTo);
createdFrom = createdFrom * 1000;
//if user only sends the fromDate toDate sets as current date
if (createdFrom != null && createdTo == null) {
operationLogFilters.setCreatedDayFrom(createdFrom);
operationLogFilters.setCreatedDayTo(timeMilli);
} else {
createdTo = createdTo * 1000;
operationLogFilters.setCreatedDayFrom(createdFrom);
operationLogFilters.setCreatedDayTo(createdTo);
}
}
if (status != null && !status.isEmpty()) {
validateStatusFiltering(status);
operationLogFilters.setStatus(status);
}
if (operationCode != null && !operationCode.isEmpty()) {
validateOperationCodeFiltering(operationCode, type);
operationLogFilters.setOperationCode(operationCode);
}
return operationLogFilters;
}
/**
* Checks if date ranges requested by user are valid
*
* @param toDate Till when created/updated dates upon to validate dates
* @param fromDate Since when created/updated dates upon to validate dates
*/
public static void validateDates(Long fromDate, Long toDate) {
Calendar date = Calendar.getInstance();
long timeMilli = date.getTimeInMillis();
timeMilli = timeMilli / 1000;
//if user only sends toDate
if (fromDate == null && toDate != null) {
String msg = "Request parameter must sent with the from date parameter";
log.error(msg);
throw new InputValidationException(
new ErrorResponse.ErrorResponseBuilder()
.setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg).build());
}
//if user sends future dates
if (fromDate != null && toDate != null) {
if (timeMilli < fromDate || timeMilli < toDate) {
String msg = "Bad Request cannot apply future dates";
log.error(msg);
throw new InputValidationException(
new ErrorResponse.ErrorResponseBuilder()
.setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg).build());
}
}
//if user send future dates - only when from date sends
if (fromDate != null && toDate == null) {
if (fromDate > timeMilli) {
String msg = "Bad Request cannot apply future dates";
log.error(msg);
throw new InputValidationException(
new ErrorResponse.ErrorResponseBuilder()
.setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg).build());
}
}
}
/**
* Checks if user requested operation status codes are valid.
*
* @param status status codes upon to filter operation logs using status
*/
public static void validateStatusFiltering(List<String> status) {
for (int i = 0; i < status.size(); i++) {
if (Constants.OperationStatus.COMPLETED.toUpperCase().equals(status.get(i))
|| Constants.OperationStatus.ERROR.toUpperCase().equals(status.get(i))
|| Constants.OperationStatus.NOTNOW.toUpperCase().equals(status.get(i))
|| Constants.OperationStatus.REPEATED.toUpperCase().equals(status.get(i))
|| Constants.OperationStatus.PENDING.toUpperCase().equals(status.get(i))
|| Constants.OperationStatus.IN_PROGRESS.toUpperCase().equals(status.get(i))) {
} else {
String msg = "Invalid status type: " + status + ". \nValid status types are COMPLETED | ERROR | " +
"IN_PROGRESS | NOTNOW | PENDING | REPEATED";
log.error(msg);
throw new InputValidationException(new ErrorResponse.ErrorResponseBuilder()
.setCode(HttpStatus.SC_BAD_REQUEST)
.setMessage(msg).build());
}
}
}
/**
* Checks if user requested operation codes are valid.
*
* @param operationCode operation codes upon to filter operation logs using operation codes
* @param type status codes upon to filter operation logs using status
*/
public static void validateOperationCodeFiltering(List<String> operationCode, String type)
throws DeviceTypeNotFoundException, DeviceManagementException {
int count = 0;
List<Feature> features;
DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService();
FeatureManager fm = dms.getFeatureManager(type);
features = fm.getFeatures("operation");
for (String oc : operationCode) {
for (Feature f : features) {
if (f.getCode().equals(oc)) {
count++;
break;
}
}
}
if (!(count == operationCode.size())) {
String msg = "Requested Operation code invalid";
log.error(msg);
throw new InputValidationException(new ErrorResponse.ErrorResponseBuilder()
.setCode(HttpStatus.SC_BAD_REQUEST)
.setMessage(msg).build());
}
}
/**
* Validate if the metaData and metaKey values are non empty & in proper format.
*

@ -648,24 +648,28 @@ public class DeviceManagementServiceImplTest {
@Test(description = "Testing getting operation list of a device")
public void testGetDeviceOperations() {
List<String> operationCodes = new ArrayList<>();
List<String> statusCodes = new ArrayList<>();
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Response response = this.deviceManagementService
.getDeviceOperations(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), "", 10, 5, DEFAULT_USERNAME,
DEFAULT_OWNERSHIP);
DEFAULT_OWNERSHIP, null, null, null, null, operationCodes, statusCodes);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"Expects to return HTTP 200 when the operation is retrieved successfully.");
}
@Test(description = "Testing getting operation list of a device when unable to retrieve operations")
public void testGetDeviceOperationsException() throws OperationManagementException {
List<String> operationCodes = new ArrayList<>();
List<String> statusCodes = new ArrayList<>();
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getOperations(Mockito.any(DeviceIdentifier.class),
Mockito.any(PaginationRequest.class))).thenThrow(new OperationManagementException());
Response response = this.deviceManagementService
.getDeviceOperations(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), "", 10, 5, DEFAULT_USERNAME,
DEFAULT_OWNERSHIP);
DEFAULT_OWNERSHIP, null, null, null, null, operationCodes, statusCodes);
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"Expects to return HTTP 500 when an exception occurred while retrieving operation list of the device");
}

@ -30,7 +30,9 @@ public class EnrolmentInfo implements Serializable {
private static final long serialVersionUID = 1998101712L;
public enum Status {
CREATED, ACTIVE, INACTIVE, UNREACHABLE, UNCLAIMED, SUSPENDED, BLOCKED, REMOVED, DISENROLLMENT_REQUESTED
CREATED, ACTIVE, INACTIVE, UNREACHABLE, UNCLAIMED, SUSPENDED, BLOCKED, REMOVED, DISENROLLMENT_REQUESTED,
CONFIGURED, READY_TO_CONNECT, RETURN_PENDING, RETURNED, DEFECTIVE, WARRANTY_PENDING, WARRANTY_SENT,
WARRANTY_REPLACED
}
public enum OwnerShip {

@ -19,7 +19,7 @@
package org.wso2.carbon.device.mgt.common;
/**
* This class holds all the constants used for IOS and Android.
* This class holds all the constants used for IOS, Android, Windows.
*/
public class MDMAppConstants {
@ -49,6 +49,29 @@ public class MDMAppConstants {
public static final String OPCODE_UNINSTALL_APPLICATION = "UNINSTALL_APPLICATION";
}
public class WindowsConstants {
private WindowsConstants() {
throw new AssertionError();
}
public static final String INSTALL_ENTERPRISE_APPLICATION = "INSTALL_ENTERPRISE_APPLICATION";
//App type constants related to window device type
public static final String MSI = "MSI";
public static final String APPX = "APPX";
//MSI Meta Key Constant
public static final String MSI_PRODUCT_ID = "Product_Id";
public static final String MSI_CONTENT_URI = "Content_Uri";
public static final String MSI_FILE_HASH = "File_Hash";
//APPX Meta Key Constant
public static final String APPX_PACKAGE_URI = "Package_Url";
public static final String APPX_DEPENDENCY_PACKAGE_URL = "Dependency_Package_Url";
public static final String APPX_CERTIFICATE_HASH = "Certificate_Hash";
public static final String APPX_ENCODED_CERT_CONTENT = "Encoded_Cert_Content";
public static final String APPX_PACKAGE_FAMILY_NAME = "Package_Family_Name";
}
public class RegistryConstants {
private RegistryConstants() {

@ -0,0 +1,72 @@
/*
* Copyright (c) 2020, 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 org.wso2.carbon.device.mgt.common;
import java.util.List;
/**
* This class carries information related to operation log filtering values which will be used in the UI to filter operations.
*/
public class OperationLogFilters {
private List<String> operationCode;
private Long createdDayFrom;
private Long createdDayTo ;
private Long updatedDayFrom;
private Long updatedDayTo ;
private List<String> status;
public OperationLogFilters() {
}
public OperationLogFilters(List<String> operationCode , Long createdDayFrom, Long createdDayTo,
Long updatedDayFrom, Long updatedDayTo, List<String> status) {
this.operationCode = operationCode;
this.createdDayFrom = createdDayFrom;
this.createdDayTo = createdDayTo;
this.updatedDayFrom = updatedDayFrom;
this.updatedDayTo = updatedDayTo;
this.status = status;
}
public List<String> getOperationCode() {
return operationCode;
}
public void setOperationCode(List<String> operationCode) {
this.operationCode = operationCode;
}
public List<String> getStatus() {
return status;
}
public void setStatus(List<String> status) {
this.status = status;
}
public Long getUpdatedDayFrom() {
return updatedDayFrom;
}
public void setUpdatedDayFrom(Long updatedDayFrom) {
this.updatedDayFrom = updatedDayFrom;
}
public Long getUpdatedDayTo() {
return updatedDayTo;
}
public void setUpdatedDayTo(Long updatedDayTo) {
this.updatedDayTo = updatedDayTo;
}
public Long getCreatedDayFrom() { return createdDayFrom; }
public void setCreatedDayFrom(Long createdDayFrom) { this.createdDayFrom = createdDayFrom; }
public Long getCreatedDayTo() { return createdDayTo; }
public void setCreatedDayTo(Long createdDayTo) { this.createdDayTo = createdDayTo; }
}

@ -42,12 +42,17 @@ public class PaginationRequest {
private String filter;
private Map<String, Object> property = new HashMap<>();
private List<String> statusList = new ArrayList<>();
private OperationLogFilters operationLogFilters = new OperationLogFilters();
public OperationLogFilters getOperationLogFilters() {
return operationLogFilters;
}
public void setOperationLogFilters(OperationLogFilters operationLogFilters) {
this.operationLogFilters = operationLogFilters;
}
public PaginationRequest(int start, int rowCount) {
this.startIndex = start;
this.rowCount = rowCount;
}
public int getStartIndex() {
return startIndex;
}

@ -62,6 +62,10 @@ public class App {
private String location;
@ApiModelProperty(name = "properties", value = "List of meta data.", required = true)
private Properties properties;
@ApiModelProperty(name = "metaData",
value = "Meta data of the application release",
required = true)
private String metaData;
public MobileAppTypes getType() {
return type;
@ -142,4 +146,8 @@ public class App {
public void setProperties(Properties properties) {
this.properties = properties;
}
public String getMetaData() { return metaData; }
public void setMetaData(String metaData) { this.metaData = metaData; }
}

@ -0,0 +1,54 @@
/*
* Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.common.app.mgt.windows;
import com.google.gson.Gson;
import java.io.Serializable;
/**
* This class represents the Windows Enterprise App Types information.
*/
public class EnterpriseApplication implements Serializable {
private HostedAppxApplication hostedAppxApplication;
private HostedMSIApplication hostedMSIApplication;
public HostedAppxApplication getHostedAppxApplication() {
return hostedAppxApplication;
}
public void setHostedAppxApplication(HostedAppxApplication hostedAppxApplication) {
this.hostedAppxApplication = hostedAppxApplication;
}
public HostedMSIApplication getHostedMSIApplication() {
return hostedMSIApplication;
}
public void setHostedMSIApplication(HostedMSIApplication hostedMSIApplication) {
this.hostedMSIApplication = hostedMSIApplication;
}
public String toJSON() {
Gson gson = new Gson();
return gson.toJson(this);
}
}

@ -0,0 +1,71 @@
/*
* Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.common.app.mgt.windows;
import java.util.List;
public class HostedAppxApplication {
private String packageUri;
private String packageFamilyName;
private List<String> dependencyPackageUri;
private String certificateHash;
private String encodedCertificate;
public String getPackageUri() {
return packageUri;
}
public void setPackageUri(String packageUri) {
this.packageUri = packageUri;
}
public String getPackageFamilyName() {
return packageFamilyName;
}
public void setPackageFamilyName(String packageFamilyName) {
this.packageFamilyName = packageFamilyName;
}
public List<String> getDependencyPackageUri() {
return dependencyPackageUri;
}
public void setDependencyPackageUri(List<String> dependencyPackageUri) {
this.dependencyPackageUri = dependencyPackageUri;
}
public String getCertificateHash() {
return certificateHash;
}
public void setCertificateHash(String certificateHash) {
this.certificateHash = certificateHash;
}
public String getEncodedCertificate() {
return encodedCertificate;
}
public void setEncodedCertificate(String encodedCertificate) {
this.encodedCertificate = encodedCertificate;
}
}

@ -0,0 +1,52 @@
/*
* Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.common.app.mgt.windows;
public class HostedMSIApplication {
private String productId;
private String contentUrl;
private String fileHash;
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public String getContentUrl() {
return contentUrl;
}
public void setContentUrl(String contentUrl) {
this.contentUrl = contentUrl;
}
public String getFileHash() {
return fileHash;
}
public void setFileHash(String fileHash) {
this.fileHash = fileHash;
}
}

@ -19,7 +19,6 @@
package org.wso2.carbon.device.mgt.common.policy.mgt;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.NonComplianceData;
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException;

@ -28,6 +28,9 @@ public class Input {
private String type;
private String placeholderValue;
private List<Rule> rules;
private String apiUrl;
private String arrayPath;
private String dataKey;
@XmlElement(name = "Type")
public String getType() {
@ -52,4 +55,31 @@ public class Input {
public List<Rule> getRules() { return rules; }
public void setRules(List<Rule> rules) { this.rules = rules; }
@XmlElement(name = "Url")
public String getUrl() {
return apiUrl;
}
public void setUrl(String url) {
this.apiUrl = url;
}
@XmlElement(name = "ArrayPath")
public String getArrayPath() {
return arrayPath;
}
public void setArrayPath(String arrayPath) {
this.arrayPath = arrayPath;
}
@XmlElement(name = "DataKey")
public String getDataKey() {
return dataKey;
}
public void setDataKey(String dataKey) {
this.dataKey = dataKey;
}
}

@ -45,6 +45,7 @@ public class Item {
private InputList inputList;
private String nullableValue;
private String divider;
private boolean isHidden;
@XmlElement(name = "Label")
public String getLabel() {
@ -207,4 +208,13 @@ public class Item {
public void setDivider(String divider) {
this.divider = divider;
}
@XmlElement(name = "Hidden")
public boolean isHidden() {
return isHidden;
}
public void setHidden(boolean hidden) {
isHidden = hidden;
}
}

@ -118,7 +118,8 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
try {
conn = this.getConnection();
String sql = "UPDATE DM_DEVICE SET NAME = ?, DESCRIPTION = ?, LAST_UPDATED_TIMESTAMP = ? " +
"WHERE DEVICE_TYPE_ID = (SELECT ID FROM DM_DEVICE_TYPE WHERE NAME = ? AND (PROVIDER_TENANT_ID = ? OR SHARED_WITH_ALL_TENANTS = ?)) " +
"WHERE DEVICE_TYPE_ID = (SELECT ID FROM DM_DEVICE_TYPE " +
"WHERE NAME = ? AND (PROVIDER_TENANT_ID = ? OR SHARED_WITH_ALL_TENANTS = ?)) " +
"AND DEVICE_IDENTIFICATION = ? AND TENANT_ID = ?";
stmt = conn.prepareStatement(sql, new String[]{"id"});
stmt.setString(1, device.getName());
@ -164,20 +165,14 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
+ "d.NAME, "
+ "t.NAME AS DEVICE_TYPE, "
+ "d.DEVICE_IDENTIFICATION "
+ "FROM DM_DEVICE d, DM_DEVICE_TYPE t";
if (deviceData.getLastModifiedDate() != null) {
sql += ", DM_DEVICE_DETAIL dt";
}
sql += " WHERE "
+ "FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE "
+ "t.NAME = ? AND "
+ "t.ID = d.DEVICE_TYPE_ID AND "
+ "d.DEVICE_IDENTIFICATION = ? AND "
+ "d.TENANT_ID = ?";
if (deviceData.getLastModifiedDate() != null) {
sql += " AND dt.DEVICE_ID = d.ID AND dt.UPDATE_TIMESTAMP > ?";
sql += " AND d.LAST_UPDATED_TIMESTAMP > ?";
}
sql += ") d1 WHERE d1.ID = e.DEVICE_ID AND ";
@ -197,7 +192,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
stmt.setString(paramIndx++, deviceData.getDeviceIdentifier().getId());
stmt.setInt(paramIndx++, tenantId);
if (deviceData.getLastModifiedDate() != null) {
stmt.setLong(paramIndx++, deviceData.getLastModifiedDate().getTime());
stmt.setTimestamp(paramIndx++, new Timestamp(deviceData.getLastModifiedDate().getTime()));
}
if (!StringUtils.isBlank(deviceData.getDeviceOwner())) {
stmt.setString(paramIndx++, deviceData.getDeviceOwner());
@ -354,15 +349,15 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
String sql = "SELECT d1.ID AS DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, " +
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.IS_TRANSFERRED, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, (SELECT d.ID, d.DESCRIPTION, d.NAME, " +
"t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION FROM DM_DEVICE d, DM_DEVICE_TYPE t, DM_DEVICE_DETAIL dt " +
"WHERE t.NAME = ? AND t.ID = d.DEVICE_TYPE_ID AND d.DEVICE_IDENTIFICATION = ? AND d.TENANT_ID = ? AND dt.DEVICE_ID = d.ID " +
"AND dt.UPDATE_TIMESTAMP > ?) d1 WHERE d1.ID = e.DEVICE_ID AND TENANT_ID = ? ORDER BY e.DATE_OF_LAST_UPDATE DESC";
"t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION FROM DM_DEVICE d, DM_DEVICE_TYPE t " +
"WHERE t.NAME = ? AND t.ID = d.DEVICE_TYPE_ID AND d.DEVICE_IDENTIFICATION = ? AND d.TENANT_ID = ? " +
"AND d.LAST_UPDATED_TIMESTAMP > ?) d1 WHERE d1.ID = e.DEVICE_ID AND TENANT_ID = ? ORDER BY e.DATE_OF_LAST_UPDATE DESC";
stmt = conn.prepareStatement(sql);
int paramIdx = 1;
stmt.setString(paramIdx++, deviceIdentifier.getType());
stmt.setString(paramIdx++, deviceIdentifier.getId());
stmt.setInt(paramIdx++, tenantId);
stmt.setLong(paramIdx++, since.getTime());
stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime()));
stmt.setInt(paramIdx, tenantId);
rs = stmt.executeQuery();
if (rs.next()) {
@ -549,11 +544,10 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
"(SELECT d.ID, d.DESCRIPTION, d.NAME, " +
"t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION " +
"FROM" +
" DM_DEVICE d, DM_DEVICE_TYPE t," +
" DM_DEVICE_DETAIL dt " +
" DM_DEVICE d, DM_DEVICE_TYPE t " +
"WHERE " +
"t.ID = d.DEVICE_TYPE_ID AND d.DEVICE_IDENTIFICATION = ? AND d.TENANT_ID = ? AND" +
" dt.DEVICE_ID = d.ID AND dt.UPDATE_TIMESTAMP > ?) d1 " +
" d.LAST_UPDATED_TIMESTAMP > ?) d1 " +
"WHERE" +
" d1.ID = e.DEVICE_ID AND TENANT_ID = ? " +
"ORDER BY " +
@ -562,7 +556,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
int paramIdx = 1;
stmt.setString(paramIdx++, deviceIdentifier);
stmt.setInt(paramIdx++, tenantId);
stmt.setLong(paramIdx++, since.getTime());
stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime()));
stmt.setInt(paramIdx, tenantId);
rs = stmt.executeQuery();
if (rs.next()) {
@ -589,14 +583,15 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
String sql = "SELECT d1.ID AS DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, " +
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.IS_TRANSFERRED, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, (SELECT d.ID, d.DESCRIPTION, d.NAME, " +
"t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION FROM DM_DEVICE d, DM_DEVICE_TYPE t, DM_DEVICE_DETAIL dt " +
"WHERE t.NAME = ? AND t.ID = d.DEVICE_TYPE_ID AND d.DEVICE_IDENTIFICATION = ? AND d.TENANT_ID = ? AND dt.DEVICE_ID = d.ID " +
"AND dt.UPDATE_TIMESTAMP > ?) d1 WHERE d1.ID = e.DEVICE_ID AND TENANT_ID = ? AND e.OWNER = ? ORDER BY e.DATE_OF_LAST_UPDATE DESC";
"t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION FROM DM_DEVICE d, DM_DEVICE_TYPE t " +
"WHERE t.NAME = ? AND t.ID = d.DEVICE_TYPE_ID AND d.DEVICE_IDENTIFICATION = ? AND d.TENANT_ID = ? " +
"AND d.LAST_UPDATED_TIMESTAMP > ?) d1 WHERE d1.ID = e.DEVICE_ID AND TENANT_ID = ? AND e.OWNER = ? " +
"ORDER BY e.DATE_OF_LAST_UPDATE DESC";
stmt = conn.prepareStatement(sql);
stmt.setString(1, deviceIdentifier.getType());
stmt.setString(2, deviceIdentifier.getId());
stmt.setInt(3, tenantId);
stmt.setLong(4, since.getTime());
stmt.setTimestamp(4, new Timestamp(since.getTime()));
stmt.setInt(5, tenantId);
stmt.setString(6, owner);
rs = stmt.executeQuery();
@ -912,16 +907,12 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
sql = sql + " AND d.NAME LIKE ?";
isDeviceNameProvided = true;
}
sql = sql + ") gd, DM_DEVICE_TYPE t";
sql = sql + ") gd, DM_DEVICE_TYPE t WHERE gd.DEVICE_TYPE_ID = t.ID";
//Add query for last updated timestamp
if (since != null) {
sql = sql + ", DM_DEVICE_DETAIL dt";
sql = sql + " AND d.LAST_UPDATED_TIMESTAMP > ?";
isSinceProvided = true;
}
sql = sql + " WHERE gd.DEVICE_TYPE_ID = t.ID";
//Add query for last updated timestamp
if (isSinceProvided) {
sql = sql + " AND dt.DEVICE_ID = gd.DEVICE_ID AND dt.UPDATE_TIMESTAMP > ?";
}
//Add the query for device-type
if (deviceType != null && !deviceType.isEmpty()) {
sql = sql + " AND t.NAME = ?";
@ -954,7 +945,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
stmt.setString(paramIdx++, deviceName + "%");
}
if (isSinceProvided) {
stmt.setLong(paramIdx++, since.getTime());
stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime()));
}
if (isDeviceTypeProvided) {
stmt.setString(paramIdx++, deviceType);
@ -1182,17 +1173,12 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
"t.NAME AS DEVICE_TYPE " +
"FROM " +
"DM_DEVICE d, " +
"DM_DEVICE_TYPE t";
"DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?";
//Add query for last updated timestamp
if (since != null) {
sql = sql + " , DM_DEVICE_DETAIL dt";
sql = sql + " AND d.LAST_UPDATED_TIMESTAMP > ?";
isSinceProvided = true;
}
sql = sql + " WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?";
//Add query for last updated timestamp
if (isSinceProvided) {
sql = sql + " AND dt.DEVICE_ID = d.ID AND dt.UPDATE_TIMESTAMP > ?";
}
if (deviceType != null && !deviceType.isEmpty()) {
sql = sql + " AND t.NAME = ?";
isDeviceTypeProvided = true;
@ -1223,7 +1209,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
int paramIdx = 1;
stmt.setInt(paramIdx++, tenantId);
if (isSinceProvided) {
stmt.setLong(paramIdx++, since.getTime());
stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime()));
}
if (isDeviceTypeProvided) {
stmt.setString(paramIdx++, request.getDeviceType());

@ -166,7 +166,35 @@ public class GeofenceDAOImpl implements GeofenceDAO {
@Override
public List<GeofenceData> getGeoFencesOfTenant(String fenceName, int tenantId)
throws DeviceManagementDAOException {
return null;
try {
List<GeofenceData> geofenceData;
Connection conn = this.getConnection();
String sql = "SELECT " +
"ID, " +
"FENCE_NAME, " +
"DESCRIPTION, " +
"LATITUDE, " +
"LONGITUDE, " +
"RADIUS, " +
"GEO_JSON, " +
"FENCE_SHAPE, " +
"OWNER, " +
"TENANT_ID " +
"FROM DM_GEOFENCE " +
"WHERE FENCE_NAME LIKE ? AND TENANT_ID = ? ";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, fenceName + "%");
stmt.setInt(2, tenantId);
try (ResultSet rst = stmt.executeQuery()) {
geofenceData = extractGeofenceData(rst);
}
}
return geofenceData;
} catch (SQLException e) {
String msg = "Error occurred while retrieving Geofence of the tenant " + tenantId;
log.error(msg, e);
throw new DeviceManagementDAOException(msg, e);
}
}
@Override

@ -36,6 +36,7 @@ import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@ -88,15 +89,12 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
"d.DEVICE_IDENTIFICATION, " +
"t.NAME AS DEVICE_TYPE " +
"FROM DM_DEVICE d, DM_DEVICE_TYPE t ";
//Add the query to filter active devices on timestamp
if (since != null) {
sql = sql + ", DM_DEVICE_DETAIL dt";
isSinceProvided = true;
}
sql = sql + " WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?";
//Add query for last updated timestamp
if (isSinceProvided) {
sql = sql + " AND dt.DEVICE_ID = d.ID AND dt.UPDATE_TIMESTAMP > ?";
if (since != null) {
sql = sql + " AND d.LAST_UPDATED_TIMESTAMP > ?";
isSinceProvided = true;
}
//Add the query for device-type
if (deviceType != null && !deviceType.isEmpty()) {
@ -132,7 +130,7 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
int paramIdx = 1;
stmt.setInt(paramIdx++, tenantId);
if (isSinceProvided) {
stmt.setLong(paramIdx++, since.getTime());
stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime()));
}
if (isDeviceTypeProvided) {
stmt.setString(paramIdx++, deviceType);
@ -232,14 +230,11 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
isDeviceNameProvided = true;
}
sql = sql + ") gd, DM_DEVICE_TYPE t";
if (since != null) {
sql = sql + ", DM_DEVICE_DETAIL dt";
isSinceProvided = true;
}
sql = sql + " WHERE gd.DEVICE_TYPE_ID = t.ID";
//Add query for last updated timestamp
if (isSinceProvided) {
sql = sql + " AND dt.DEVICE_ID = gd.DEVICE_ID AND dt.UPDATE_TIMESTAMP > ?";
if (since != null) {
sql = sql + " AND d.LAST_UPDATED_TIMESTAMP > ?";
isSinceProvided = true;
}
//Add the query for device-type
if (deviceType != null && !deviceType.isEmpty()) {
@ -274,7 +269,7 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
stmt.setString(paramIdx++, deviceName + "%");
}
if (isSinceProvided) {
stmt.setLong(paramIdx++, since.getTime());
stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime()));
}
if (isDeviceTypeProvided) {
stmt.setString(paramIdx++, deviceType);

@ -36,6 +36,7 @@ import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@ -89,17 +90,12 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl {
"d.DEVICE_IDENTIFICATION, " +
"t.NAME AS DEVICE_TYPE " +
"FROM DM_DEVICE d, " +
"DM_DEVICE_TYPE t ";
//Add the query to filter active devices on timestamp
"DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?";
//Add query for last updated timestamp
if (since != null) {
sql = sql + ", DM_DEVICE_DETAIL dt";
sql = sql + " AND d.LAST_UPDATED_TIMESTAMP > ?";
isSinceProvided = true;
}
sql = sql + " WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?";
//Add query for last updated timestamp
if (isSinceProvided) {
sql = sql + " AND dt.DEVICE_ID = d.ID AND dt.UPDATE_TIMESTAMP > ?";
}
//Add the query for device-type
if (deviceType != null && !deviceType.isEmpty()) {
sql = sql + " AND t.NAME = ?";
@ -134,7 +130,7 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl {
int paramIdx = 1;
stmt.setInt(paramIdx++, tenantId);
if (isSinceProvided) {
stmt.setLong(paramIdx++, since.getTime());
stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime()));
}
if (isDeviceTypeProvided) {
stmt.setString(paramIdx++, deviceType);
@ -235,16 +231,12 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl {
sql = sql + " AND d.NAME LIKE ?";
isDeviceNameProvided = true;
}
sql = sql + ") gd, DM_DEVICE_TYPE t";
sql = sql + ") gd, DM_DEVICE_TYPE t WHERE gd.DEVICE_TYPE_ID = t.ID";
//Add query for last updated timestamp
if (since != null) {
sql = sql + ", DM_DEVICE_DETAIL dt";
sql = sql + " AND d.LAST_UPDATED_TIMESTAMP > ?";
isSinceProvided = true;
}
sql = sql + " WHERE gd.DEVICE_TYPE_ID = t.ID";
//Add query for last updated timestamp
if (isSinceProvided) {
sql = sql + " AND dt.DEVICE_ID = gd.DEVICE_ID AND dt.UPDATE_TIMESTAMP > ?";
}
//Add the query for device-type
if (deviceType != null && !deviceType.isEmpty()) {
sql = sql + " AND t.NAME = ?";
@ -278,7 +270,7 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl {
stmt.setString(paramIdx++, deviceName + "%");
}
if (isSinceProvided) {
stmt.setLong(paramIdx++, since.getTime());
stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime()));
}
if (isDeviceTypeProvided) {
stmt.setString(paramIdx++, deviceType);

@ -35,6 +35,7 @@ import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@ -222,16 +223,12 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl {
sql = sql + " AND d.NAME LIKE ?";
isDeviceNameProvided = true;
}
sql = sql + ") gd, DM_DEVICE_TYPE t";
sql = sql + ") gd, DM_DEVICE_TYPE t WHERE gd.DEVICE_TYPE_ID = t.ID";
//Add query for last updated timestamp
if (since != null) {
sql = sql + ", DM_DEVICE_DETAIL dt";
sql = sql + " AND d.LAST_UPDATED_TIMESTAMP > ?";
isSinceProvided = true;
}
sql = sql + " WHERE gd.DEVICE_TYPE_ID = t.ID";
//Add query for last updated timestamp
if (isSinceProvided) {
sql = sql + " AND dt.DEVICE_ID = gd.DEVICE_ID AND dt.UPDATE_TIMESTAMP > ?";
}
//Add the query for device-type
if (deviceType != null && !deviceType.isEmpty()) {
sql = sql + " AND t.NAME = ?";
@ -265,7 +262,7 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl {
stmt.setString(paramIdx++, deviceName + "%");
}
if (isSinceProvided) {
stmt.setLong(paramIdx++, since.getTime());
stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime()));
}
if (isDeviceTypeProvided) {
stmt.setString(paramIdx++, deviceType);

@ -37,6 +37,7 @@ import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@ -89,17 +90,12 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl {
"d.NAME, " +
"d.DEVICE_IDENTIFICATION, " +
"t.NAME AS DEVICE_TYPE " +
"FROM DM_DEVICE d, DM_DEVICE_TYPE t ";
//Add the query to filter active devices on timestamp
"FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?";
//Add query for last updated timestamp
if (since != null) {
sql = sql + ", DM_DEVICE_DETAIL dt";
sql = sql + " AND d.LAST_UPDATED_TIMESTAMP > ?";
isSinceProvided = true;
}
sql = sql + " WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?";
//Add query for last updated timestamp
if (isSinceProvided) {
sql = sql + " AND dt.DEVICE_ID = d.ID AND dt.UPDATE_TIMESTAMP > ?";
}
//Add the query for device-type
if (deviceType != null && !deviceType.isEmpty()) {
sql = sql + " AND t.NAME = ?";
@ -134,7 +130,7 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl {
int paramIdx = 1;
stmt.setInt(paramIdx++, tenantId);
if (isSinceProvided) {
stmt.setLong(paramIdx++, since.getTime());
stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime()));
}
if (isDeviceTypeProvided) {
stmt.setString(paramIdx++, deviceType);
@ -234,16 +230,12 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl {
sql = sql + " AND d.NAME LIKE ?";
isDeviceNameProvided = true;
}
sql = sql + ") gd, DM_DEVICE_TYPE t";
sql = sql + ") gd, DM_DEVICE_TYPE t WHERE gd.DEVICE_TYPE_ID = t.ID";
//Add query for last updated timestamp
if (since != null) {
sql = sql + ", DM_DEVICE_DETAIL dt";
sql = sql + " AND d.LAST_UPDATED_TIMESTAMP > ?";
isSinceProvided = true;
}
sql = sql + " WHERE gd.DEVICE_TYPE_ID = t.ID";
//Add query for last updated timestamp
if (isSinceProvided) {
sql = sql + " AND dt.DEVICE_ID = gd.DEVICE_ID AND dt.UPDATE_TIMESTAMP > ?";
}
//Add the query for device-type
if (deviceType != null && !deviceType.isEmpty()) {
sql = sql + " AND t.NAME = ?";
@ -277,7 +269,7 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl {
stmt.setString(paramIdx++, deviceName + "%");
}
if (isSinceProvided) {
stmt.setLong(paramIdx++, since.getTime());
stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime()));
}
if (isDeviceTypeProvided) {
stmt.setString(paramIdx++, deviceType);

@ -627,7 +627,7 @@ public class OperationManagerImpl implements OperationManager {
operations.add(operation);
}
paginationResult = new PaginationResult();
int count = operationDAO.getOperationCountForDevice(enrolmentId);
int count = operationDAO.getOperationCountForDevice(enrolmentId, request);
paginationResult.setData(operations);
paginationResult.setRecordsTotal(count);
paginationResult.setRecordsFiltered(count);

@ -44,7 +44,7 @@ public interface OperationDAO {
List<? extends Operation> getOperationsForDevice(int enrolmentId) throws OperationManagementDAOException;
int getOperationCountForDevice(int enrolmentId) throws OperationManagementDAOException;
int getOperationCountForDevice(int enrolmentId, PaginationRequest request) throws OperationManagementDAOException;
List<? extends Operation> getOperationsForDevice(int enrolmentId, PaginationRequest request) throws OperationManagementDAOException;

@ -44,12 +44,16 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.LinkedList;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Date;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* This class holds the generic implementation of OperationDAO which can be used to support ANSI db syntax.
@ -648,22 +652,31 @@ public class GenericOperationDAOImpl implements OperationDAO {
PreparedStatement stmt = null;
ResultSet rs = null;
Activity activity = null;
int responseId = 0;
List<ActivityStatus> activityStatusList = new ArrayList<>();
try {
Connection conn = OperationManagementDAOFactory.getConnection();
String sql = "SELECT eom.ENROLMENT_ID, eom.OPERATION_ID, eom.ID AS EOM_MAPPING_ID, dor.ID AS OP_RES_ID,\n" +
"de.DEVICE_ID, d.DEVICE_IDENTIFICATION, \n" +
"d.DEVICE_TYPE_ID, dt.NAME AS DEVICE_TYPE_NAME, eom.STATUS, eom.CREATED_TIMESTAMP, \n" +
"eom.UPDATED_TIMESTAMP, op.OPERATION_CODE, op.TYPE AS OPERATION_TYPE, dor.OPERATION_RESPONSE, \n" +
"dor.RECEIVED_TIMESTAMP, dor.IS_LARGE_RESPONSE, op.INITIATED_BY FROM DM_ENROLMENT_OP_MAPPING AS eom \n" +
"INNER JOIN DM_OPERATION AS op ON op.ID=eom.OPERATION_ID\n" +
"INNER JOIN DM_ENROLMENT AS de ON de.ID=eom.ENROLMENT_ID\n" +
"INNER JOIN DM_DEVICE AS d ON d.ID=de.DEVICE_ID \n" +
"INNER JOIN DM_DEVICE_TYPE AS dt ON dt.ID=d.DEVICE_TYPE_ID\n" +
"LEFT JOIN DM_DEVICE_OPERATION_RESPONSE AS dor ON dor.ENROLMENT_ID=de.id \n" +
"AND dor.OPERATION_ID = eom.OPERATION_ID\n" +
"WHERE eom.OPERATION_ID = ? AND de.device_id = ? AND de.TENANT_ID = ?";
String sql = "SELECT "
+ "eom.ENROLMENT_ID, "
+ "eom.OPERATION_ID, eom.ID AS EOM_MAPPING_ID, "
+ "dor.ID AS OP_RES_ID, "
+ "de.DEVICE_ID, "
+ "d.DEVICE_IDENTIFICATION, "
+ "d.DEVICE_TYPE_ID, dt.NAME AS DEVICE_TYPE_NAME, "
+ "eom.STATUS, eom.CREATED_TIMESTAMP, "
+ "eom.UPDATED_TIMESTAMP, "
+ "op.OPERATION_CODE, "
+ "op.TYPE AS OPERATION_TYPE, "
+ "dor.OPERATION_RESPONSE, "
+ "dor.RECEIVED_TIMESTAMP, "
+ "dor.IS_LARGE_RESPONSE, "
+ "op.INITIATED_BY FROM DM_ENROLMENT_OP_MAPPING AS eom "
+ "INNER JOIN DM_OPERATION AS op ON op.ID=eom.OPERATION_ID "
+ "INNER JOIN DM_ENROLMENT AS de ON de.ID=eom.ENROLMENT_ID "
+ "INNER JOIN DM_DEVICE AS d ON d.ID=de.DEVICE_ID "
+ "INNER JOIN DM_DEVICE_TYPE AS dt ON dt.ID=d.DEVICE_TYPE_ID "
+ "LEFT JOIN DM_DEVICE_OPERATION_RESPONSE AS dor ON dor.ENROLMENT_ID=de.id "
+ "AND dor.OPERATION_ID = eom.OPERATION_ID "
+ "WHERE eom.OPERATION_ID = ? AND de.device_id = ? AND de.TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, operationId);
@ -680,37 +693,40 @@ public class GenericOperationDAOImpl implements OperationDAO {
activity = new Activity();
activity.setActivityId(DeviceManagementConstants.OperationAttributes.ACTIVITY + operationId);
activity.setType(Activity.Type.valueOf(rs.getString("OPERATION_TYPE")));
activity.setCreatedTimeStamp(new java.util.Date(rs.getLong(("CREATED_TIMESTAMP")) * 1000).toString());
activity.setCreatedTimeStamp(
new java.util.Date(rs.getLong(("CREATED_TIMESTAMP")) * 1000).toString());
activity.setCode(rs.getString("OPERATION_CODE"));
activity.setInitiatedBy(rs.getString("INITIATED_BY"));
}
if (enrolmentId != rs.getInt("ENROLMENT_ID")) {
activityStatus = new ActivityStatus();
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
deviceIdentifier.setId(rs.getString("DEVICE_IDENTIFICATION"));
deviceIdentifier.setType(rs.getString("DEVICE_TYPE_NAME"));
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(rs.getString("DEVICE_IDENTIFICATION"),
rs.getString("DEVICE_TYPE_NAME"));
activityStatus.setDeviceIdentifier(deviceIdentifier);
activityStatus.setStatus(ActivityStatus.Status.valueOf(rs.getString("STATUS")));
List<OperationResponse> operationResponses = new ArrayList<>();
if (rs.getInt("UPDATED_TIMESTAMP") != 0) {
activityStatus.setUpdatedTimestamp(new java.util.Date(rs.getLong(("UPDATED_TIMESTAMP")) * 1000).toString());
operationResponses.add(OperationDAOUtil.getOperationResponse(rs));
activityStatus.setUpdatedTimestamp(
new java.util.Date(rs.getLong(("UPDATED_TIMESTAMP")) * 1000).toString());
if (rs.getBoolean("IS_LARGE_RESPONSE")) {
largeResponseIDs.add(rs.getInt("OP_RES_ID"));
} else {
operationResponses.add(OperationDAOUtil.getOperationResponse(rs));
}
}
activityStatus.setResponses(operationResponses);
activityStatusList.add(activityStatus);
enrolmentId = rs.getInt("ENROLMENT_ID");
activity.setActivityStatus(activityStatusList);
} else {
if (rs.getInt("UPDATED_TIMESTAMP") != 0) {
responseId = rs.getInt("OP_RES_ID");
if (rs.getBoolean("IS_LARGE_RESPONSE")) {
largeResponseIDs.add(responseId);
largeResponseIDs.add(rs.getInt("OP_RES_ID"));
} else {
if (activityStatus == null) {
activityStatus = new ActivityStatus();
}
activityStatus.getResponses().add(OperationDAOUtil.getOperationResponse(rs));
}
}
@ -1327,70 +1343,247 @@ public class GenericOperationDAOImpl implements OperationDAO {
@Override
public List<? extends Operation> getOperationsForDevice(int enrolmentId, PaginationRequest request)
throws OperationManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
Operation operation;
List<Operation> operations = new ArrayList<Operation>();
String createdTo = null;
String createdFrom = null;
DateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
boolean isCreatedDayProvided = false;
boolean isUpdatedDayProvided = false; //updated day = received day
boolean isOperationCodeProvided = false;
boolean isStatusProvided = false;
if (request.getOperationLogFilters().getCreatedDayFrom() != null) {
createdFrom = simple.format(request.getOperationLogFilters().getCreatedDayFrom());
}
if (request.getOperationLogFilters().getCreatedDayTo() != null) {
createdTo = simple.format(request.getOperationLogFilters().getCreatedDayTo());
}
Long updatedFrom = request.getOperationLogFilters().getUpdatedDayFrom();
Long updatedTo = request.getOperationLogFilters().getUpdatedDayTo();
List<String> operationCode = request.getOperationLogFilters().getOperationCode();
List<String> status = request.getOperationLogFilters().getStatus();
String sql = "SELECT " +
"o.ID, " +
"TYPE, " +
"o.CREATED_TIMESTAMP, " +
"o.RECEIVED_TIMESTAMP, " +
"o.OPERATION_CODE, " +
"om.STATUS, " +
"om.ID AS OM_MAPPING_ID, " +
"om.UPDATED_TIMESTAMP " +
"FROM " +
"DM_OPERATION o " +
"INNER JOIN " +
"(SELECT dm.OPERATION_ID, " +
"dm.ID, " +
"dm.STATUS, " +
"dm.UPDATED_TIMESTAMP " +
"FROM " +
"DM_ENROLMENT_OP_MAPPING dm " +
"WHERE " +
"dm.ENROLMENT_ID = ?";
if (updatedFrom != null && updatedFrom != 0 && updatedTo != null && updatedTo != 0) {
sql = sql + " AND dm.UPDATED_TIMESTAMP BETWEEN ? AND ?";
isUpdatedDayProvided = true;
}
sql = sql + ") om ON o.ID = om.OPERATION_ID ";
if (createdFrom != null && !createdFrom.isEmpty() && createdTo != null && !createdTo.isEmpty()) {
sql = sql + " WHERE o.CREATED_TIMESTAMP BETWEEN ? AND ?";
isCreatedDayProvided = true;
}
if ((isCreatedDayProvided) && (status != null && !status.isEmpty())) {
int size = status.size();
sql = sql + " AND (om.STATUS = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR om.STATUS = ?";
}
sql = sql + ")";
isStatusProvided = true;
} else if ((!isCreatedDayProvided) && (status != null && !status.isEmpty())) {
int size = status.size();
sql = sql + " WHERE (om.STATUS = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR om.STATUS = ?";
}
sql = sql + ")";
isStatusProvided = true;
}
if ((isCreatedDayProvided || isStatusProvided) && (operationCode != null && !operationCode.isEmpty())) {
int size = operationCode.size();
sql = sql + " AND (o.OPERATION_CODE = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR o.OPERATION_CODE = ?";
}
sql = sql + ")";
isOperationCodeProvided = true;
} else if ((!isCreatedDayProvided && !isStatusProvided) && (operationCode != null && !operationCode.isEmpty())) {
int size = operationCode.size();
sql = sql + " WHERE (o.OPERATION_CODE = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR o.OPERATION_CODE = ?";
}
sql = sql + ")";
isOperationCodeProvided = true;
}
sql = sql + " ORDER BY o.CREATED_TIMESTAMP DESC LIMIT ?,?";
try {
Connection conn = OperationManagementDAOFactory.getConnection();
String sql = "SELECT o.ID, o.TYPE, o.CREATED_TIMESTAMP, o.RECEIVED_TIMESTAMP, " +
"o.OPERATION_CODE, om.STATUS, om.ID AS OM_MAPPING_ID, om.UPDATED_TIMESTAMP FROM DM_OPERATION o " +
"INNER JOIN (SELECT * FROM DM_ENROLMENT_OP_MAPPING dm " +
"WHERE dm.ENROLMENT_ID = ?) om ON o.ID = om.OPERATION_ID " +
"ORDER BY o.CREATED_TIMESTAMP DESC, o.ID DESC LIMIT ?,?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, enrolmentId);
stmt.setInt(2, request.getStartIndex());
stmt.setInt(3, request.getRowCount());
rs = stmt.executeQuery();
while (rs.next()) {
operation = new Operation();
operation.setId(rs.getInt("ID"));
operation.setType(Operation.Type.valueOf(rs.getString("TYPE")));
operation.setCreatedTimeStamp(rs.getTimestamp("CREATED_TIMESTAMP").toString());
if (rs.getLong("UPDATED_TIMESTAMP") == 0) {
operation.setReceivedTimeStamp("");
} else {
operation.setReceivedTimeStamp(
new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP") * 1000)).toString());
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
int paramIndex = 1;
stmt.setInt(paramIndex++, enrolmentId);
if (isUpdatedDayProvided) {
stmt.setLong(paramIndex++, updatedFrom);
stmt.setLong(paramIndex++, updatedTo);
}
if (isCreatedDayProvided) {
stmt.setString(paramIndex++, createdFrom);
stmt.setString(paramIndex++, createdTo);
}
if (isStatusProvided) {
int size = status.size();
for (int i = 0; i < size; i++) {
stmt.setString(paramIndex++, status.get(i));
}
}
if (isOperationCodeProvided) {
int size = operationCode.size();
for (int i = 0; i < size; i++) {
stmt.setString(paramIndex++, operationCode.get(i));
}
}
stmt.setInt(paramIndex++, request.getStartIndex());
stmt.setInt(paramIndex, request.getRowCount());
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
operation = new Operation();
operation.setId(rs.getInt("ID"));
operation.setType(Operation.Type.valueOf(rs.getString("TYPE")));
operation.setCreatedTimeStamp(rs.getTimestamp("CREATED_TIMESTAMP").toString());
if (rs.getLong("UPDATED_TIMESTAMP") == 0) {
operation.setReceivedTimeStamp("");
} else {
operation.setReceivedTimeStamp(
new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP") * 1000)).toString());
}
operation.setCode(rs.getString("OPERATION_CODE"));
operation.setStatus(Operation.Status.valueOf(rs.getString("STATUS")));
OperationDAOUtil.setActivityId(operation, rs.getInt("ID"));
operations.add(operation);
}
}
operation.setCode(rs.getString("OPERATION_CODE"));
operation.setStatus(Operation.Status.valueOf(rs.getString("STATUS")));
OperationDAOUtil.setActivityId(operation, rs.getInt("ID"));
operations.add(operation);
}
} catch (SQLException e) {
throw new OperationManagementDAOException("SQL error occurred while retrieving the operation " +
"available for the device'" + enrolmentId + "' with status '", e);
} finally {
OperationManagementDAOUtil.cleanupResources(stmt, rs);
}
return operations;
}
@Override
public int getOperationCountForDevice(int enrolmentId) throws OperationManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
int operationCount = 0;
public int getOperationCountForDevice(int enrolmentId, PaginationRequest request)
throws OperationManagementDAOException {
String createdTo = null;
String createdFrom = null;
DateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
if (request.getOperationLogFilters().getCreatedDayFrom() != null) {
createdFrom = simple.format(request.getOperationLogFilters().getCreatedDayFrom());
}
if (request.getOperationLogFilters().getCreatedDayTo() != null) {
createdTo = simple.format(request.getOperationLogFilters().getCreatedDayTo());
}
Long updatedFrom = request.getOperationLogFilters().getUpdatedDayFrom();
Long updatedTo = request.getOperationLogFilters().getUpdatedDayTo();
List<String> operationCodes = request.getOperationLogFilters().getOperationCode();
List<String> status = request.getOperationLogFilters().getStatus();
boolean isCreatedDayProvided = false;
boolean isUpdatedDayProvided = false;
boolean isOperationCodeProvided = false;
boolean isStatusProvided = false;
String sql = "SELECT "
+ "COUNT(o.ID) AS OPERATION_COUNT "
+ "FROM "
+ "DM_OPERATION o "
+ "INNER JOIN "
+ "(SELECT dm.OPERATION_ID, "
+ "dm.ID, "
+ "dm.STATUS, "
+ "dm.UPDATED_TIMESTAMP "
+ "FROM "
+ "DM_ENROLMENT_OP_MAPPING dm "
+ "WHERE "
+ "dm.ENROLMENT_ID = ?";
if (updatedFrom != null && updatedFrom != 0 && updatedTo != null && updatedTo != 0) {
sql += " AND dm.UPDATED_TIMESTAMP BETWEEN ? AND ?";
isUpdatedDayProvided = true;
}
sql += ") om ON o.ID = om.OPERATION_ID ";
if (createdFrom != null && !createdFrom.isEmpty() && createdTo != null && !createdTo.isEmpty()) {
sql += " WHERE o.CREATED_TIMESTAMP BETWEEN ? AND ?";
isCreatedDayProvided = true;
}
if (status != null && !status.isEmpty()) {
if (isCreatedDayProvided) {
sql += " AND (om.STATUS = ? ";
} else {
sql += " WHERE (om.STATUS = ? ";
}
sql = IntStream.range(0, status.size() - 1).mapToObj(i -> " OR om.STATUS = ?")
.collect(Collectors.joining("", sql, ""));
sql += ")";
isStatusProvided = true;
}
if (operationCodes != null && !operationCodes.isEmpty()) {
if (isCreatedDayProvided || isStatusProvided) {
sql += " AND (o.OPERATION_CODE = ? ";
} else {
sql += " WHERE (o.OPERATION_CODE = ? ";
}
sql = IntStream.range(0, operationCodes.size() - 1).mapToObj(i -> " OR o.OPERATION_CODE = ?")
.collect(Collectors.joining("", sql, ""));
sql += ")";
isOperationCodeProvided = true;
}
try {
conn = OperationManagementDAOFactory.getConnection();
String sql = "SELECT COUNT(ID) AS OPERATION_COUNT FROM DM_ENROLMENT_OP_MAPPING WHERE ENROLMENT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, enrolmentId);
rs = stmt.executeQuery();
if (rs.next()) {
operationCount = rs.getInt("OPERATION_COUNT");
Connection conn = OperationManagementDAOFactory.getConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
int paramIndex = 1;
stmt.setInt(paramIndex++, enrolmentId);
if (isUpdatedDayProvided) {
stmt.setLong(paramIndex++, updatedFrom);
stmt.setLong(paramIndex++, updatedTo);
}
if (isCreatedDayProvided) {
stmt.setString(paramIndex++, createdFrom);
stmt.setString(paramIndex++, createdTo);
}
if (isStatusProvided) {
for (String s : status) {
stmt.setString(paramIndex++, s);
}
}
if (isOperationCodeProvided) {
for (String s : operationCodes) {
stmt.setString(paramIndex++, s);
}
}
try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) {
return rs.getInt("OPERATION_COUNT");
}
}
}
} catch (SQLException e) {
throw new OperationManagementDAOException("Error occurred while getting the operations count for enrolment: "
+ enrolmentId, e);
} finally {
OperationManagementDAOUtil.cleanupResources(stmt, rs);
String msg = "SQL error occurred while retrieving the operation count of the device" + enrolmentId
+ " for search query";
log.error(msg, e);
throw new OperationManagementDAOException(msg, e);
}
return operationCount;
return 0;
}
@Override

@ -37,11 +37,13 @@ import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.LinkedList;
/**
* This class holds the implementation of OperationDAO which can be used to support Oracle db syntax.
@ -53,44 +55,140 @@ public class OracleOperationDAOImpl extends GenericOperationDAOImpl {
@Override
public List<? extends Operation> getOperationsForDevice(int enrolmentId, PaginationRequest request)
throws OperationManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
Operation operation;
List<Operation> operations = new ArrayList<Operation>();
String createdTo = null;
String createdFrom = null;
DateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
boolean isCreatedDayProvided = false;
boolean isUpdatedDayProvided = false; //updated day = received day
boolean isOperationCodeProvided = false;
boolean isStatusProvided = false;
if (request.getOperationLogFilters().getCreatedDayFrom() != null) {
createdFrom = simple.format(request.getOperationLogFilters().getCreatedDayFrom());
}
if (request.getOperationLogFilters().getCreatedDayTo() != null) {
createdTo = simple.format(request.getOperationLogFilters().getCreatedDayTo());
}
Long updatedFrom = request.getOperationLogFilters().getUpdatedDayFrom();
Long updatedTo = request.getOperationLogFilters().getUpdatedDayTo();
List<String> operationCode = request.getOperationLogFilters().getOperationCode();
List<String> status = request.getOperationLogFilters().getStatus();
String sql = "SELECT " +
"o.ID, " +
"TYPE, " +
"o.CREATED_TIMESTAMP, " +
"o.RECEIVED_TIMESTAMP, " +
"o.OPERATION_CODE, " +
"om.STATUS, " +
"om.ID AS OM_MAPPING_ID, " +
"om.UPDATED_TIMESTAMP " +
"FROM " +
"DM_OPERATION o " +
"INNER JOIN " +
"(SELECT " +
"dm.OPERATION_ID, " +
"dm.ID, " +
"dm.STATUS, " +
"dm.UPDATED_TIMESTAMP " +
"FROM " +
"DM_ENROLMENT_OP_MAPPING dm " +
"WHERE " +
"dm.ENROLMENT_ID = ?";
if (updatedFrom != null && updatedFrom != 0 && updatedTo != null && updatedTo != 0) {
sql = sql + " AND dm.UPDATED_TIMESTAMP BETWEEN ? AND ?";
isUpdatedDayProvided = true;
}
sql = sql + ") om ON o.ID = om.OPERATION_ID ";
if (createdFrom != null && !createdFrom.isEmpty() && createdTo != null && !createdTo.isEmpty()) {
sql = sql + " WHERE o.CREATED_TIMESTAMP BETWEEN ? AND ?";
isCreatedDayProvided = true;
}
if ((isCreatedDayProvided) && (status != null && !status.isEmpty())) {
int size = status.size();
sql = sql + " AND (om.STATUS = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR om.STATUS = ?";
}
sql = sql + ")";
isStatusProvided = true;
} else if ((!isCreatedDayProvided) && (status != null && !status.isEmpty())) {
int size = status.size();
sql = sql + " WHERE (om.STATUS = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR om.STATUS = ?";
}
sql = sql + ")";
isStatusProvided = true;
}
if ((isCreatedDayProvided || isStatusProvided) && (operationCode != null && !operationCode.isEmpty())) {
int size = operationCode.size();
sql = sql + " AND (o.OPERATION_CODE = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR o.OPERATION_CODE = ?";
}
sql = sql + ")";
isOperationCodeProvided = true;
} else if ((!isCreatedDayProvided && !isStatusProvided) && (operationCode != null && !operationCode.isEmpty())) {
int size = operationCode.size();
sql = sql + " WHERE (o.OPERATION_CODE = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR o.OPERATION_CODE = ?";
}
sql = sql + ")";
isOperationCodeProvided = true;
}
sql = sql + " ORDER BY o.CREATED_TIMESTAMP DESC FFSET ? ROWS FETCH NEXT ? ROWS ONLY";
int paramIndex = 1;
try {
Connection conn = OperationManagementDAOFactory.getConnection();
String sql = "SELECT o.ID, TYPE, o.CREATED_TIMESTAMP, o.RECEIVED_TIMESTAMP, "
+ "o.OPERATION_CODE, om.STATUS, om.ID AS OM_MAPPING_ID, om.UPDATED_TIMESTAMP FROM DM_OPERATION o "
+ "INNER JOIN (SELECT dm.OPERATION_ID, dm.ID, dm.STATUS, dm.UPDATED_TIMESTAMP FROM DM_ENROLMENT_OP_MAPPING dm "
+ "WHERE dm.ENROLMENT_ID = ?) om ON o.ID = om.OPERATION_ID ORDER BY o.CREATED_TIMESTAMP DESC "
+ "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, enrolmentId);
stmt.setInt(2, request.getStartIndex());
stmt.setInt(3, request.getRowCount());
rs = stmt.executeQuery();
while (rs.next()) {
operation = new Operation();
operation.setId(rs.getInt("ID"));
operation.setType(Operation.Type.valueOf(rs.getString("TYPE")));
operation.setCreatedTimeStamp(rs.getTimestamp("CREATED_TIMESTAMP").toString());
if (rs.getTimestamp("RECEIVED_TIMESTAMP") == null) {
operation.setReceivedTimeStamp("");
} else {
operation.setReceivedTimeStamp(rs.getTimestamp("RECEIVED_TIMESTAMP").toString());
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(paramIndex++, enrolmentId);
if (isUpdatedDayProvided) {
stmt.setLong(paramIndex++, updatedFrom);
stmt.setLong(paramIndex++, updatedTo);
}
if (isCreatedDayProvided) {
stmt.setString(paramIndex++, createdFrom);
stmt.setString(paramIndex++, createdTo);
}
if (isStatusProvided) {
int size = status.size();
for (int i = 0; i < size; i++) {
stmt.setString(paramIndex++, status.get(i));
}
}
if (isOperationCodeProvided) {
int size = operationCode.size();
for (int i = 0; i < size; i++) {
stmt.setString(paramIndex++, operationCode.get(i));
}
}
stmt.setInt(paramIndex++, request.getStartIndex());
stmt.setInt(paramIndex, request.getRowCount());
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
operation = new Operation();
operation.setId(rs.getInt("ID"));
operation.setType(Operation.Type.valueOf(rs.getString("TYPE")));
operation.setCreatedTimeStamp(rs.getTimestamp("CREATED_TIMESTAMP").toString());
if (rs.getTimestamp("RECEIVED_TIMESTAMP") == null) {
operation.setReceivedTimeStamp("");
} else {
operation.setReceivedTimeStamp(rs.getTimestamp("RECEIVED_TIMESTAMP").toString());
}
operation.setCode(rs.getString("OPERATION_CODE"));
operation.setStatus(Operation.Status.valueOf(rs.getString("STATUS")));
OperationDAOUtil.setActivityId(operation, rs.getInt("ID"));
operations.add(operation);
}
}
operation.setCode(rs.getString("OPERATION_CODE"));
operation.setStatus(Operation.Status.valueOf(rs.getString("STATUS")));
OperationDAOUtil.setActivityId(operation, rs.getInt("ID"));
operations.add(operation);
}
} catch (SQLException e) {
throw new OperationManagementDAOException(
"SQL error occurred while retrieving the operation " + "available for the device'" + enrolmentId
+ "' with status '", e);
} finally {
OperationManagementDAOUtil.cleanupResources(stmt, rs);
}
return operations;
}

@ -32,9 +32,11 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
/**
* This class holds the implementation of OperationDAO which can be used to support PostgreSQL db syntax.
@ -44,42 +46,139 @@ public class PostgreSQLOperationDAOImpl extends GenericOperationDAOImpl {
@Override
public List<? extends Operation> getOperationsForDevice(int enrolmentId, PaginationRequest request)
throws OperationManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
Operation operation;
List<Operation> operations = new ArrayList<Operation>();
String createdTo = null;
String createdFrom = null;
DateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
boolean isCreatedDayProvided = false;
boolean isUpdatedDayProvided = false; //updated day = received day
boolean isOperationCodeProvided = false;
boolean isStatusProvided = false;
if (request.getOperationLogFilters().getCreatedDayFrom() != null) {
createdFrom = simple.format(request.getOperationLogFilters().getCreatedDayFrom());
}
if (request.getOperationLogFilters().getCreatedDayTo() != null) {
createdTo = simple.format(request.getOperationLogFilters().getCreatedDayTo());
}
Long updatedFrom = request.getOperationLogFilters().getUpdatedDayFrom();
Long updatedTo = request.getOperationLogFilters().getUpdatedDayTo();
List<String> operationCode = request.getOperationLogFilters().getOperationCode();
List<String> status = request.getOperationLogFilters().getStatus();
String sql = "SELECT " +
"o.ID, " +
"TYPE, " +
"o.CREATED_TIMESTAMP, " +
"o.RECEIVED_TIMESTAMP, " +
"o.OPERATION_CODE, " +
"om.STATUS, " +
"om.ID AS OM_MAPPING_ID, " +
"om.UPDATED_TIMESTAMP " +
"FROM " +
"DM_OPERATION o " +
"INNER JOIN " +
"(SELECT " +
"dm.OPERATION_ID, " +
"dm.ID, " +
"dm.STATUS, " +
"dm.UPDATED_TIMESTAMP " +
"FROM " +
"DM_ENROLMENT_OP_MAPPING dm " +
"WHERE " +
"dm.ENROLMENT_ID = ?";
if (updatedFrom != null && updatedFrom != 0 && updatedTo != null && updatedTo != 0) {
sql = sql + " AND dm.UPDATED_TIMESTAMP BETWEEN ? AND ?";
isUpdatedDayProvided = true;
}
sql = sql + ") om ON o.ID = om.OPERATION_ID ";
if (createdFrom != null && !createdFrom.isEmpty() && createdTo != null && !createdTo.isEmpty()) {
sql = sql + " WHERE o.CREATED_TIMESTAMP BETWEEN ? AND ?";
isCreatedDayProvided = true;
}
if ((isCreatedDayProvided) && (status != null && !status.isEmpty())) {
int size = status.size();
sql = sql + " AND (om.STATUS = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR om.STATUS = ?";
}
sql = sql + ")";
isStatusProvided = true;
} else if ((!isCreatedDayProvided) && (status != null && !status.isEmpty())) {
int size = status.size();
sql = sql + " WHERE (om.STATUS = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR om.STATUS = ?";
}
sql = sql + ")";
isStatusProvided = true;
}
if ((isCreatedDayProvided || isStatusProvided) && (operationCode != null && !operationCode.isEmpty())) {
int size = operationCode.size();
sql = sql + " AND (o.OPERATION_CODE = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR o.OPERATION_CODE = ?";
}
sql = sql + ")";
isOperationCodeProvided = true;
} else if ((!isCreatedDayProvided && !isStatusProvided) && (operationCode != null && !operationCode.isEmpty())) {
int size = operationCode.size();
sql = sql + " WHERE (o.OPERATION_CODE = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR o.OPERATION_CODE = ?";
}
sql = sql + ")";
isOperationCodeProvided = true;
}
sql = sql + " ORDER BY o.CREATED_TIMESTAMP DESC LIMIT ? OFFSET ?";
int paramIndex = 1;
try {
Connection conn = OperationManagementDAOFactory.getConnection();
String sql = "SELECT o.ID, o.TYPE, o.CREATED_TIMESTAMP, o.RECEIVED_TIMESTAMP, " +
"o.OPERATION_CODE, om.STATUS FROM DM_OPERATION o " +
"INNER JOIN (SELECT * FROM DM_ENROLMENT_OP_MAPPING dm " +
"WHERE dm.ENROLMENT_ID = ?) om ON o.ID = om.OPERATION_ID ORDER BY o.CREATED_TIMESTAMP DESC LIMIT ? OFFSET ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, enrolmentId);
stmt.setInt(2, request.getRowCount());
stmt.setInt(3, request.getStartIndex());
rs = stmt.executeQuery();
while (rs.next()) {
operation = new Operation();
operation.setId(rs.getInt("ID"));
operation.setType(Operation.Type.valueOf(rs.getString("TYPE")));
operation.setCreatedTimeStamp(rs.getTimestamp("CREATED_TIMESTAMP").toString());
if (rs.getTimestamp("RECEIVED_TIMESTAMP") == null) {
operation.setReceivedTimeStamp("");
} else {
operation.setReceivedTimeStamp(rs.getTimestamp("RECEIVED_TIMESTAMP").toString());
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(paramIndex++, enrolmentId);
if (isUpdatedDayProvided) {
stmt.setLong(paramIndex++, updatedFrom);
stmt.setLong(paramIndex++, updatedTo);
}
if (isCreatedDayProvided) {
stmt.setString(paramIndex++, createdFrom);
stmt.setString(paramIndex++, createdTo);
}
if (isStatusProvided) {
int size = status.size();
for (int i = 0; i < size; i++) {
stmt.setString(paramIndex++, status.get(i));
}
}
if (isOperationCodeProvided) {
int size = operationCode.size();
for (int i = 0; i < size; i++) {
stmt.setString(paramIndex++, operationCode.get(i));
}
}
stmt.setInt(paramIndex++, request.getStartIndex());
stmt.setInt(paramIndex, request.getRowCount());
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
operation = new Operation();
operation.setId(rs.getInt("ID"));
operation.setType(Operation.Type.valueOf(rs.getString("TYPE")));
operation.setCreatedTimeStamp(rs.getTimestamp("CREATED_TIMESTAMP").toString());
if (rs.getTimestamp("RECEIVED_TIMESTAMP") == null) {
operation.setReceivedTimeStamp("");
} else {
operation.setReceivedTimeStamp(rs.getTimestamp("RECEIVED_TIMESTAMP").toString());
}
operation.setCode(rs.getString("OPERATION_CODE"));
operation.setStatus(Operation.Status.valueOf(rs.getString("STATUS")));
OperationDAOUtil.setActivityId(operation, rs.getInt("ID"));
operations.add(operation);
}
}
operation.setCode(rs.getString("OPERATION_CODE"));
operation.setStatus(Operation.Status.valueOf(rs.getString("STATUS")));
OperationDAOUtil.setActivityId(operation, rs.getInt("ID"));
operations.add(operation);
}
} catch (SQLException e) {
throw new OperationManagementDAOException("SQL error occurred while retrieving the operation " +
"available for the device'" + enrolmentId, e);
} finally {
OperationManagementDAOUtil.cleanupResources(stmt, rs);
"available for the device'" + enrolmentId, e);
}
return operations;
}

@ -56,12 +56,13 @@ import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.LinkedList;
/**
* This class holds the implementation of OperationDAO which can be used to support SQLServer db syntax.
*/
@ -72,44 +73,142 @@ public class SQLServerOperationDAOImpl extends GenericOperationDAOImpl {
@Override
public List<? extends Operation> getOperationsForDevice(int enrolmentId, PaginationRequest request)
throws OperationManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
Operation operation;
List<Operation> operations = new ArrayList<Operation>();
String createdTo = null;
String createdFrom = null;
DateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
boolean isCreatedDayProvided = false;
boolean isUpdatedDayProvided = false; //updated day = received day
boolean isOperationCodeProvided = false;
boolean isStatusProvided = false;
if (request.getOperationLogFilters().getCreatedDayFrom() != null) {
createdFrom = simple.format(request.getOperationLogFilters().getCreatedDayFrom());
}
if (request.getOperationLogFilters().getCreatedDayTo() != null) {
createdTo = simple.format(request.getOperationLogFilters().getCreatedDayTo());
}
Long updatedFrom = request.getOperationLogFilters().getUpdatedDayFrom();
Long updatedTo = request.getOperationLogFilters().getUpdatedDayTo();
List<String> operationCode = request.getOperationLogFilters().getOperationCode();
List<String> status = request.getOperationLogFilters().getStatus();
String sql = "SELECT " +
"o.ID, " +
"TYPE, " +
"o.CREATED_TIMESTAMP, " +
"o.RECEIVED_TIMESTAMP, " +
"o.OPERATION_CODE, " +
"om.STATUS, " +
"om.ID AS OM_MAPPING_ID, " +
"om.UPDATED_TIMESTAMP " +
"FROM " +
"DM_OPERATION o " +
"INNER JOIN " +
"(SELECT " +
"dm.OPERATION_ID, " +
"dm.ID, " +
"dm.STATUS, " +
"dm.UPDATED_TIMESTAMP " +
"FROM " +
"DM_ENROLMENT_OP_MAPPING dm " +
"WHERE " +
"dm.ENROLMENT_ID = ?";
if (updatedFrom != null && updatedFrom != 0 && updatedTo != null && updatedTo != 0) {
sql = sql + " AND dm.UPDATED_TIMESTAMP BETWEEN ? AND ?";
isUpdatedDayProvided = true;
}
sql = sql + ") om ON o.ID = om.OPERATION_ID ";
if (createdFrom != null && !createdFrom.isEmpty() && createdTo != null && !createdTo.isEmpty()) {
sql = sql + " WHERE o.CREATED_TIMESTAMP BETWEEN ? AND ?";
isCreatedDayProvided = true;
}
if ((isCreatedDayProvided) && (status != null && !status.isEmpty())) {
int size = status.size();
sql = sql + " AND (om.STATUS = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR om.STATUS = ?";
}
sql = sql + ")";
isStatusProvided = true;
} else if ((!isCreatedDayProvided) && (status != null && !status.isEmpty())) {
int size = status.size();
sql = sql + " WHERE (om.STATUS = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR om.STATUS = ?";
}
sql = sql + ")";
isStatusProvided = true;
}
if ((isCreatedDayProvided || isStatusProvided) && (operationCode != null && !operationCode.isEmpty())) {
// sql = sql + " AND o.OPERATION_CODE = ? ";
int size = operationCode.size();
sql = sql + " AND (o.OPERATION_CODE = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR o.OPERATION_CODE = ?";
}
sql = sql + ")";
isOperationCodeProvided = true;
} else if ((!isCreatedDayProvided && !isStatusProvided) && (operationCode != null && !operationCode.isEmpty())) {
//sql = sql + " WHERE o.OPERATION_CODE = ? ";
int size = operationCode.size();
sql = sql + " WHERE (o.OPERATION_CODE = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR o.OPERATION_CODE = ?";
}
sql = sql + ")";
isOperationCodeProvided = true;
}
sql = sql + " ORDER BY o.CREATED_TIMESTAMP DESC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
int paramIndex = 1;
try {
Connection conn = OperationManagementDAOFactory.getConnection();
String sql = "SELECT o.ID, TYPE, o.CREATED_TIMESTAMP, o.RECEIVED_TIMESTAMP, " +
"o.OPERATION_CODE, om.STATUS, om.ID AS OM_MAPPING_ID, om.UPDATED_TIMESTAMP FROM DM_OPERATION o " +
"INNER JOIN (SELECT dm.OPERATION_ID, dm.ID, dm.STATUS, dm.UPDATED_TIMESTAMP FROM DM_ENROLMENT_OP_MAPPING dm " +
"WHERE dm.ENROLMENT_ID = ?) om ON o.ID = om.OPERATION_ID ORDER BY o.CREATED_TIMESTAMP DESC " +
"OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, enrolmentId);
stmt.setInt(2, request.getStartIndex());
stmt.setInt(3, request.getRowCount());
rs = stmt.executeQuery();
while (rs.next()) {
operation = new Operation();
operation.setId(rs.getInt("ID"));
operation.setType(Operation.Type.valueOf(rs.getString("TYPE")));
operation.setCreatedTimeStamp(rs.getTimestamp("CREATED_TIMESTAMP").toString());
if (rs.getLong("UPDATED_TIMESTAMP") == 0) {
operation.setReceivedTimeStamp("");
} else {
operation.setReceivedTimeStamp(
new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP") * 1000)).toString());
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(paramIndex++, enrolmentId);
if (isUpdatedDayProvided) {
stmt.setLong(paramIndex++, updatedFrom);
stmt.setLong(paramIndex++, updatedTo);
}
if (isCreatedDayProvided) {
stmt.setString(paramIndex++, createdFrom);
stmt.setString(paramIndex++, createdTo);
}
if (isStatusProvided) {
int size = status.size();
for (int i = 0; i < size; i++) {
stmt.setString(paramIndex++, status.get(i));
}
}
if (isOperationCodeProvided) {
int size = operationCode.size();
for (int i = 0; i < size; i++) {
stmt.setString(paramIndex++, operationCode.get(i));
}
}
stmt.setInt(paramIndex++, request.getStartIndex());
stmt.setInt(paramIndex, request.getRowCount());
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
operation = new Operation();
operation.setId(rs.getInt("ID"));
operation.setType(Operation.Type.valueOf(rs.getString("TYPE")));
operation.setCreatedTimeStamp(rs.getTimestamp("CREATED_TIMESTAMP").toString());
if (rs.getLong("UPDATED_TIMESTAMP") == 0) {
operation.setReceivedTimeStamp("");
} else {
operation.setReceivedTimeStamp(
new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP") * 1000)).toString());
}
operation.setCode(rs.getString("OPERATION_CODE"));
operation.setStatus(Operation.Status.valueOf(rs.getString("STATUS")));
OperationDAOUtil.setActivityId(operation, rs.getInt("ID"));
operations.add(operation);
}
}
operation.setCode(rs.getString("OPERATION_CODE"));
operation.setStatus(Operation.Status.valueOf(rs.getString("STATUS")));
OperationDAOUtil.setActivityId(operation, rs.getInt("ID"));
operations.add(operation);
}
} catch (SQLException e) {
throw new OperationManagementDAOException("SQL error occurred while retrieving the operations " +
"available for the device '" + enrolmentId + "'", e);
} finally {
OperationManagementDAOUtil.cleanupResources(stmt, rs);
"available for the device '" + enrolmentId + "'", e);
}
return operations;
}

@ -150,7 +150,6 @@ import java.io.IOException;
import java.io.StringWriter;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;

@ -0,0 +1,146 @@
/*
* Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.util;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.MDMAppConstants;
import org.wso2.carbon.device.mgt.common.app.mgt.App;
import org.wso2.carbon.device.mgt.common.app.mgt.windows.EnterpriseApplication;
import org.wso2.carbon.device.mgt.common.app.mgt.windows.HostedAppxApplication;
import org.wso2.carbon.device.mgt.common.app.mgt.windows.HostedMSIApplication;
import org.wso2.carbon.device.mgt.common.exceptions.UnknownApplicationTypeException;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.core.operation.mgt.ProfileOperation;
import java.util.ArrayList;
import java.util.List;
/**
* This class contains the all the operations related to Windows.
*/
public class MDMWindowsOperationUtil {
private static final Log log = LogFactory.getLog(MDMWindowsOperationUtil.class);
/**
* This method is used to create Install Authentication operation.
*
* @param application MobileApp application
* @return operation object
* @throws UnknownApplicationTypeException
*/
public static Operation createInstallAppOperation(App application) throws UnknownApplicationTypeException {
ProfileOperation operation = new ProfileOperation();
operation.setCode(MDMAppConstants.WindowsConstants.INSTALL_ENTERPRISE_APPLICATION);
operation.setType(Operation.Type.PROFILE);
String appType = windowsAppType(application.getName());
String metaData = application.getMetaData();
JsonArray metaJsonArray = jsonStringToArray(metaData);
switch (application.getType()) {
case ENTERPRISE:
EnterpriseApplication enterpriseApplication = new EnterpriseApplication();
if (appType.equalsIgnoreCase(MDMAppConstants.WindowsConstants.APPX)) {
HostedAppxApplication hostedAppxApplication = new HostedAppxApplication();
List<String> dependencyPackageList = new ArrayList<>();
for (int i = 0; i < metaJsonArray.size(); i++) {
JsonElement metaElement = metaJsonArray.get(i);
JsonObject metaObject = metaElement.getAsJsonObject();
if (MDMAppConstants.WindowsConstants.APPX_PACKAGE_URI.equals(metaObject.get("key").getAsString())) {
hostedAppxApplication.setPackageUri(metaObject.get("value").getAsString().trim());
}
else if (MDMAppConstants.WindowsConstants.APPX_PACKAGE_FAMILY_NAME.equals(metaObject.get("key").getAsString())) {
hostedAppxApplication.setPackageFamilyName(metaObject.get("value").getAsString().trim());
}
else if (MDMAppConstants.WindowsConstants.APPX_DEPENDENCY_PACKAGE_URL.equals(metaObject.get("key").getAsString())
&& metaObject.has("value")) {
dependencyPackageList.add(metaObject.get("value").getAsString().trim());
hostedAppxApplication.setDependencyPackageUri(dependencyPackageList);
}
else if (MDMAppConstants.WindowsConstants.APPX_CERTIFICATE_HASH.equals(metaObject.get("key").getAsString())
&& metaObject.has("value")) {
hostedAppxApplication.setCertificateHash(metaObject.get("value").getAsString().trim());
}
else if (MDMAppConstants.WindowsConstants.APPX_ENCODED_CERT_CONTENT.equals(metaObject.get("key").getAsString())
&& metaObject.has("value")) {
hostedAppxApplication.setEncodedCertificate(metaObject.get("value").getAsString().trim());
}
}
enterpriseApplication.setHostedAppxApplication(hostedAppxApplication);
} else if (appType.equalsIgnoreCase(MDMAppConstants.WindowsConstants.MSI)) {
HostedMSIApplication hostedMSIApplication = new HostedMSIApplication();
for (int i = 0; i < metaJsonArray.size(); i++) {
JsonElement metaElement = metaJsonArray.get(i);
JsonObject metaObject = metaElement.getAsJsonObject();
if (MDMAppConstants.WindowsConstants.MSI_PRODUCT_ID.equals(metaObject.get("key").getAsString())) {
hostedMSIApplication.setProductId(metaObject.get("value").getAsString().trim());
}
else if (MDMAppConstants.WindowsConstants.MSI_CONTENT_URI.equals(metaObject.get("key").getAsString())) {
hostedMSIApplication.setContentUrl(metaObject.get("value").getAsString().trim());
}
else if (MDMAppConstants.WindowsConstants.MSI_FILE_HASH.equals(metaObject.get("key").getAsString())) {
hostedMSIApplication.setFileHash(metaObject.get("value").getAsString().trim());
}
}
enterpriseApplication.setHostedMSIApplication(hostedMSIApplication);
}
operation.setPayLoad(enterpriseApplication.toJSON());
break;
default:
String msg = "Application type " + application.getType() + " is not supported";
log.error(msg);
throw new UnknownApplicationTypeException(msg);
}
return operation;
}
/**
* Method to get the installer file extension type for windows type apps(either appx or msi)
*
* @param installerName of the app type
* @return string extension of the windows app types(either appx or msi)
*/
public static String windowsAppType(String installerName) {
String extension = installerName.substring(installerName.lastIndexOf(".") + 1);
return extension;
}
/**
* Method to convert Json String to Json Array
*
* @param metaData metaData string array object containing the windows app type specific parameters
* @return the metaData Json String as Json Array
*/
public static JsonArray jsonStringToArray(String metaData) {
JsonArray metaJsonArray = new JsonParser().parse(metaData).getAsJsonArray();
return metaJsonArray;
}
}

@ -25,7 +25,6 @@ import org.wso2.carbon.device.mgt.common.policy.mgt.Policy;
import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager;
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceFeature;
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.NonComplianceData;
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException;
import java.util.ArrayList;
import java.util.List;
@ -35,10 +34,10 @@ import java.util.List;
*/
public class DefaultPolicyMonitoringManager implements PolicyMonitoringManager {
private static Log log = LogFactory.getLog(DefaultPolicyMonitoringManager.class);
private static final Log log = LogFactory.getLog(DefaultPolicyMonitoringManager.class);
@Override
public NonComplianceData checkPolicyCompliance(DeviceIdentifier deviceIdentifier, Policy policy, Object response)
throws PolicyComplianceException {
public NonComplianceData checkPolicyCompliance(DeviceIdentifier deviceIdentifier, Policy policy, Object response) {
if (log.isDebugEnabled()) {
log.debug("Checking policy compliance status of device '" + deviceIdentifier.getId() + "'");
}

@ -188,14 +188,6 @@ public class MonitoringDAOImpl implements MonitoringDAO {
stmt.setInt(4, tenantId);
stmt.setInt(5, enrolmentId);
stmt.executeUpdate();
// generatedKeys = stmt.getGeneratedKeys();
// if (generatedKeys.next()) {
// return generatedKeys.getInt(1);
// } else {
// return 0;
// }
} catch (SQLException e) {
throw new MonitoringDAOException("Error occurred while deleting the none compliance to the database.", e);
} finally {
@ -442,7 +434,7 @@ public class MonitoringDAOImpl implements MonitoringDAO {
Connection conn;
PreparedStatement stmt = null;
ResultSet resultSet = null;
List<ComplianceFeature> complianceFeatures = new ArrayList<ComplianceFeature>();
List<ComplianceFeature> complianceFeatures = new ArrayList<>();
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
@ -488,8 +480,7 @@ public class MonitoringDAOImpl implements MonitoringDAO {
}
private Connection getConnection() throws MonitoringDAOException {
private Connection getConnection() {
return PolicyManagementDAOFactory.getConnection();
}
}

@ -75,41 +75,13 @@ public class PolicyDAOImpl implements PolicyDAO {
return persistPolicy(policy);
}
// @Override
// public Policy addPolicyToDeviceType(String deviceType, Policy policy) throws PolicyManagerDAOException {
// Connection conn;
// PreparedStatement stmt = null;
// try {
// conn = this.getConnection();
// String query = "INSERT INTO DM_DEVICE_TYPE_POLICY (DEVICE_TYPE_ID, POLICY_ID) VALUES (?, ?)";
// stmt = conn.prepareStatement(query);
// stmt.setInt(1, getDeviceTypeId(deviceType));
// stmt.setInt(2, policy.getId());
// stmt.executeQuery();
// } catch (SQLException e) {
// throw new PolicyManagerDAOException("Error occurred while adding the device type policy to database.", e);
// } finally {
// PolicyManagementDAOUtil.cleanupResources(stmt, null);
// }
// return policy;
//
// }
@Override
public Policy addPolicyToRole(List<String> rolesToAdd, Policy policy) throws PolicyManagerDAOException {
Connection conn;
PreparedStatement insertStmt = null;
// PreparedStatement deleteStmt = null;
// final List<String> currentRoles = this.getPolicy(policy.getId()).getRoles();
//
// SetReferenceTransformer<String> transformer = new SetReferenceTransformer<String>();
//
// transformer.transform(currentRoles, rolesToAdd);
// rolesToAdd = transformer.getObjectsToAdd();
// List<String> rolesToDelete = transformer.getObjectsToRemove();
try {
conn = this.getConnection();
if (rolesToAdd.size() > 0) {
if (!rolesToAdd.isEmpty()) {
String query = "INSERT INTO DM_ROLE_POLICY (ROLE_NAME, POLICY_ID) VALUES (?, ?)";
insertStmt = conn.prepareStatement(query);
for (String role : rolesToAdd) {
@ -119,16 +91,6 @@ public class PolicyDAOImpl implements PolicyDAO {
}
insertStmt.executeBatch();
}
// if (rolesToDelete.size() > 0){
// String deleteQuery = "DELETE FROM DM_ROLE_POLICY WHERE ROLE_NAME=? AND POLICY_ID=?";
// deleteStmt = conn.prepareStatement(deleteQuery);
// for (String role : rolesToDelete) {
// deleteStmt.setString(1, role);
// deleteStmt.setInt(2, policy.getId());
// deleteStmt.addBatch();
// }
// deleteStmt.executeBatch();
// }
} catch (SQLException e) {
throw new PolicyManagerDAOException("Error occurred while adding the role name with policy to database", e);
} finally {
@ -146,14 +108,14 @@ public class PolicyDAOImpl implements PolicyDAO {
final List<String> currentRoles = previousPolicy.getRoles();
SetReferenceTransformer<String> transformer = new SetReferenceTransformer<String>();
SetReferenceTransformer<String> transformer = new SetReferenceTransformer<>();
transformer.transform(currentRoles, rolesToAdd);
rolesToAdd = transformer.getObjectsToAdd();
List<String> rolesToDelete = transformer.getObjectsToRemove();
try {
conn = this.getConnection();
if (rolesToAdd.size() > 0) {
if (!rolesToAdd.isEmpty()) {
String query = "INSERT INTO DM_ROLE_POLICY (ROLE_NAME, POLICY_ID) VALUES (?, ?)";
insertStmt = conn.prepareStatement(query);
for (String role : rolesToAdd) {
@ -163,7 +125,7 @@ public class PolicyDAOImpl implements PolicyDAO {
}
insertStmt.executeBatch();
}
if (rolesToDelete.size() > 0) {
if (!rolesToDelete.isEmpty()) {
String deleteQuery = "DELETE FROM DM_ROLE_POLICY WHERE ROLE_NAME=? AND POLICY_ID=?";
deleteStmt = conn.prepareStatement(deleteQuery);
for (String role : rolesToDelete) {
@ -186,17 +148,9 @@ public class PolicyDAOImpl implements PolicyDAO {
public Policy addPolicyToUser(List<String> usersToAdd, Policy policy) throws PolicyManagerDAOException {
Connection conn;
PreparedStatement insertStmt = null;
// PreparedStatement deleteStmt = null;
// final List<String> currentUsers = this.getPolicy(policy.getId()).getUsers();
//
// SetReferenceTransformer<String> transformer = new SetReferenceTransformer<String>();
//
// transformer.transform(currentUsers, usersToAdd);
// usersToAdd = transformer.getObjectsToAdd();
// List<String> usersToDelete = transformer.getObjectsToRemove();
try {
conn = this.getConnection();
if (usersToAdd.size() > 0) {
if (!usersToAdd.isEmpty()) {
String query = "INSERT INTO DM_USER_POLICY (POLICY_ID, USERNAME) VALUES (?, ?)";
insertStmt = conn.prepareStatement(query);
for (String username : usersToAdd) {
@ -206,22 +160,10 @@ public class PolicyDAOImpl implements PolicyDAO {
}
insertStmt.executeBatch();
}
// if (usersToDelete.size() > 0){
// String deleteQuery = "DELETE FROM DM_USER_POLICY WHERE USERNAME=? AND POLICY_ID=?";
// deleteStmt = conn.prepareStatement(deleteQuery);
// for (String username : usersToDelete) {
// deleteStmt.setString(1, username);
// deleteStmt.setInt(2, policy.getId());
// deleteStmt.addBatch();
// }
// deleteStmt.executeBatch();
// }
} catch (SQLException e) {
throw new PolicyManagerDAOException("Error occurred while adding the user name with policy to database", e);
} finally {
PolicyManagementDAOUtil.cleanupResources(insertStmt, null);
// PolicyManagementDAOUtil.cleanupResources(deleteStmt, null);
}
return policy;
}
@ -234,14 +176,14 @@ public class PolicyDAOImpl implements PolicyDAO {
PreparedStatement deleteStmt = null;
final List<String> currentUsers = policy.getUsers();
SetReferenceTransformer<String> transformer = new SetReferenceTransformer<String>();
SetReferenceTransformer<String> transformer = new SetReferenceTransformer<>();
transformer.transform(currentUsers, usersToAdd);
usersToAdd = transformer.getObjectsToAdd();
List<String> usersToDelete = transformer.getObjectsToRemove();
try {
conn = this.getConnection();
if (usersToAdd.size() > 0) {
if (!usersToAdd.isEmpty()) {
String query = "INSERT INTO DM_USER_POLICY (POLICY_ID, USERNAME) VALUES (?, ?)";
insertStmt = conn.prepareStatement(query);
for (String username : usersToAdd) {
@ -251,7 +193,7 @@ public class PolicyDAOImpl implements PolicyDAO {
}
insertStmt.executeBatch();
}
if (usersToDelete.size() > 0) {
if (!usersToDelete.isEmpty()) {
String deleteQuery = "DELETE FROM DM_USER_POLICY WHERE USERNAME=? AND POLICY_ID=?";
deleteStmt = conn.prepareStatement(deleteQuery);
for (String username : usersToDelete) {
@ -328,7 +270,6 @@ public class PolicyDAOImpl implements PolicyDAO {
String query = "SELECT ACTION_TYPE, CORRECTIVE_POLICY_ID, FEATURE_ID, POLICY_ID, IS_REACTIVE " +
"FROM DM_POLICY_CORRECTIVE_ACTION ";
try (PreparedStatement stmt = conn.prepareStatement(query)) {
List<CorrectiveAction> correctiveActions = new ArrayList<>();
return extractCorrectivePolicies(stmt);
}
} catch (SQLException e) {
@ -826,7 +767,7 @@ public class PolicyDAOImpl implements PolicyDAO {
Connection conn;
PreparedStatement stmt = null;
ResultSet resultSet = null;
List<Criterion> criteria = new ArrayList<Criterion>();
List<Criterion> criteria = new ArrayList<>();
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
conn = this.getConnection();
@ -912,8 +853,6 @@ public class PolicyDAOImpl implements PolicyDAO {
}
stmt.executeBatch();
}
// stmt.executeUpdate();
} catch (SQLException | IOException e) {
throw new PolicyManagerDAOException("Error occurred while inserting the criterion properties " +
"to database", e);
@ -928,7 +867,7 @@ public class PolicyDAOImpl implements PolicyDAO {
Connection conn;
PreparedStatement stmt = null;
ResultSet resultSet = null;
List<PolicyCriterion> criteria = new ArrayList<PolicyCriterion>();
List<PolicyCriterion> criteria = new ArrayList<>();
try {
conn = this.getConnection();
String query = "SELECT DPC.ID, DPC.CRITERIA_ID, DPCP.PROP_KEY, DPCP.PROP_VALUE, DPCP.CONTENT FROM " +
@ -1152,7 +1091,6 @@ public class PolicyDAOImpl implements PolicyDAO {
Connection conn;
PreparedStatement stmt = null;
ResultSet resultSet = null;
List<Policy> policies = new ArrayList<Policy>();
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
@ -1180,7 +1118,7 @@ public class PolicyDAOImpl implements PolicyDAO {
Connection conn;
PreparedStatement stmt = null;
ResultSet resultSet = null;
List<Integer> deviceIdList = new ArrayList<Integer>();
List<Integer> deviceIdList = new ArrayList<>();
try {
conn = this.getConnection();
String query = "SELECT * FROM DM_DEVICE_POLICY WHERE POLICY_ID = ?";
@ -1204,7 +1142,7 @@ public class PolicyDAOImpl implements PolicyDAO {
Connection conn;
PreparedStatement stmt = null;
ResultSet resultSet = null;
List<String> roleNames = new ArrayList<String>();
List<String> roleNames = new ArrayList<>();
try {
conn = this.getConnection();
String query = "SELECT * FROM DM_ROLE_POLICY WHERE POLICY_ID = ?";
@ -1229,7 +1167,7 @@ public class PolicyDAOImpl implements PolicyDAO {
PreparedStatement stmt = null;
ResultSet resultSet = null;
List<String> users = new ArrayList<String>();
List<String> users = new ArrayList<>();
try {
conn = this.getConnection();
String query = "SELECT * FROM DM_USER_POLICY WHERE POLICY_ID = ?";
@ -1387,7 +1325,7 @@ public class PolicyDAOImpl implements PolicyDAO {
Connection conn;
PreparedStatement stmt = null;
ResultSet resultSet = null;
List<Integer> policyIds = new ArrayList<Integer>();
List<Integer> policyIds = new ArrayList<>();
try {
conn = this.getConnection();
String query = "SELECT * FROM DM_DEVICE_POLICY WHERE DEVICE_ID = ? ";
@ -1411,7 +1349,7 @@ public class PolicyDAOImpl implements PolicyDAO {
Connection conn;
PreparedStatement stmt = null;
ResultSet resultSet = null;
List<Integer> policyIds = new ArrayList<Integer>();
List<Integer> policyIds = new ArrayList<>();
try {
conn = this.getConnection();
String query = "SELECT * FROM DM_ROLE_POLICY WHERE ROLE_NAME = ? ";
@ -1435,7 +1373,7 @@ public class PolicyDAOImpl implements PolicyDAO {
Connection conn;
PreparedStatement stmt = null;
ResultSet resultSet = null;
List<Integer> policyIds = new ArrayList<Integer>();
List<Integer> policyIds = new ArrayList<>();
try {
conn = this.getConnection();
String query = "SELECT * FROM DM_USER_POLICY WHERE USERNAME = ? ";
@ -1563,16 +1501,6 @@ public class PolicyDAOImpl implements PolicyDAO {
try {
conn = this.getConnection();
// String userPolicy = "DELETE FROM DM_USER_POLICY WHERE POLICY_ID = ?";
// stmt = conn.prepareStatement(userPolicy);
// stmt.setInt(1, policyId);
// stmt.executeUpdate();
//
// String rolePolicy = "DELETE FROM DM_ROLE_POLICY WHERE POLICY_ID = ?";
// stmt = conn.prepareStatement(rolePolicy);
// stmt.setInt(1, policyId);
// stmt.executeUpdate();
String devicePolicy = "DELETE FROM DM_DEVICE_POLICY WHERE POLICY_ID = ?";
stmt = conn.prepareStatement(devicePolicy);
stmt.setInt(1, policyId);
@ -1601,7 +1529,7 @@ public class PolicyDAOImpl implements PolicyDAO {
}
}
private Connection getConnection() throws PolicyManagerDAOException {
private Connection getConnection() {
return PolicyManagementDAOFactory.getConnection();
}
@ -1821,15 +1749,6 @@ public class PolicyDAOImpl implements PolicyDAO {
} finally {
PolicyManagementDAOUtil.cleanupResources(stmt, resultSet);
}
//
// if (policy != null && log.isDebugEnabled()) {
// log.debug("Applied policy logging details started ------------------");
// log.debug("Applied policy name " + policy.getPolicyName() + "for the device id " + deviceId);
// log.debug(policy.getCompliance());
// log.debug(policy.getId());
// log.debug(policy.getPriorityId());
// log.debug("Applied policy logging details finished....");
// }
return policy;
}

@ -41,7 +41,8 @@ import java.util.Map;
public class DelegationTask implements Task {
private static final Log log = LogFactory.getLog(DelegationTask.class);
private PolicyConfiguration policyConfiguration = DeviceConfigurationManager.getInstance().getDeviceManagementConfig().getPolicyConfiguration();
private PolicyConfiguration policyConfiguration = DeviceConfigurationManager.getInstance()
.getDeviceManagementConfig().getPolicyConfiguration();
@Override
public void setProperties(Map<String, String> map) {
@ -73,21 +74,17 @@ public class DelegationTask implements Task {
List<Device> toBeNotified;
for (String deviceType : deviceTypes) {
try {
devices = new ArrayList<>();
toBeNotified = new ArrayList<>();
devices.addAll(service.getAllDevices(deviceType, false));
//HashMap<Integer, Integer> deviceIdPolicy = policyManager.getAppliedPolicyIdsDeviceIds();
devices = new ArrayList<>(service.getAllDevices(deviceType, false));
for (Device device : devices) {
// if (deviceIdPolicy.containsKey(device.getId())) {
if (device != null && device.getEnrolmentInfo() != null
&& device.getEnrolmentInfo().getStatus() != EnrolmentInfo.Status.REMOVED) {
&& device.getEnrolmentInfo().getStatus() != EnrolmentInfo.Status.REMOVED) {
toBeNotified.add(device);
}
// }
}
if (!toBeNotified.isEmpty()) {
PolicyEnforcementDelegator enforcementDelegator = new PolicyEnforcementDelegatorImpl
(toBeNotified, updatedPolicyDeviceList.getUpdatedPolicyIds());
PolicyEnforcementDelegator enforcementDelegator = new PolicyEnforcementDelegatorImpl(
toBeNotified, updatedPolicyDeviceList.getUpdatedPolicyIds());
enforcementDelegator.delegate();
}
} catch (DeviceManagementException e) {

@ -122,7 +122,6 @@ public class PolicyEnforcementDelegatorImpl implements PolicyEnforcementDelegato
return null;
}
return policy;
//return PolicyManagementDataHolder.getInstance().getPolicyEvaluationPoint().getEffectivePolicy(identifier);
} catch (PolicyEvaluationException | PolicyManagementException e) {
String msg = "Error occurred while retrieving the effective policy for devices.";
log.error(msg, e);
@ -135,7 +134,7 @@ public class PolicyEnforcementDelegatorImpl implements PolicyEnforcementDelegato
PolicyDelegationException {
try {
String type = null;
if (deviceIdentifiers.size() > 0) {
if (!deviceIdentifiers.isEmpty()) {
type = deviceIdentifiers.get(0).getType();
}
PolicyManagementDataHolder.getInstance().getDeviceManagementService().addOperation(type,
@ -161,7 +160,7 @@ public class PolicyEnforcementDelegatorImpl implements PolicyEnforcementDelegato
public void addPolicyRevokeOperation(List<DeviceIdentifier> deviceIdentifiers) throws PolicyDelegationException {
try {
String type = null;
if (deviceIdentifiers.size() > 0) {
if (!deviceIdentifiers.isEmpty()) {
type = deviceIdentifiers.get(0).getType();
}
PolicyManagementDataHolder.getInstance().getDeviceManagementService().addOperation(type,

@ -153,7 +153,7 @@ public class ComplianceDecisionPointImpl implements ComplianceDecisionPoint {
PolicyOperation policyOperation = new PolicyOperation();
policyOperation.setEnabled(true);
policyOperation.setType(Operation.Type.POLICY);
policyOperation.setCode(PolicyOperation.POLICY_OPERATION_CODE);
policyOperation.setCode(PolicyManagementConstants.MONITOR_POLICY_BUNDLE);
if (complianceData.isCompletePolicy()) {
List<ProfileFeature> effectiveFeatures = policy.getProfile().getProfileFeaturesList();

@ -34,10 +34,8 @@ import org.wso2.carbon.policy.mgt.common.*;
import org.wso2.carbon.policy.mgt.core.cache.PolicyCacheManager;
import org.wso2.carbon.policy.mgt.core.cache.impl.PolicyCacheManagerImpl;
import org.wso2.carbon.policy.mgt.core.internal.PolicyManagementDataHolder;
import org.wso2.carbon.policy.mgt.core.mgt.FeatureManager;
import org.wso2.carbon.policy.mgt.core.mgt.PolicyManager;
import org.wso2.carbon.policy.mgt.core.mgt.ProfileManager;
import org.wso2.carbon.policy.mgt.core.mgt.impl.FeatureManagerImpl;
import org.wso2.carbon.policy.mgt.core.mgt.impl.PolicyManagerImpl;
import org.wso2.carbon.policy.mgt.core.mgt.impl.ProfileManagerImpl;
import org.wso2.carbon.policy.mgt.core.util.PolicyManagementConstants;
@ -53,28 +51,18 @@ public class PolicyAdministratorPointImpl implements PolicyAdministratorPoint {
private PolicyManager policyManager;
private ProfileManager profileManager;
private FeatureManager featureManager;
private PolicyCacheManager cacheManager;
private PolicyConfiguration policyConfiguration;
// private PolicyEnforcementDelegator delegator;
public PolicyAdministratorPointImpl() {
this.policyManager = new PolicyManagerImpl();
this.profileManager = new ProfileManagerImpl();
this.featureManager = new FeatureManagerImpl();
this.cacheManager = PolicyCacheManagerImpl.getInstance();
this.policyConfiguration = DeviceConfigurationManager.getInstance().getDeviceManagementConfig().getPolicyConfiguration();
// this.delegator = new PolicyEnforcementDelegatorImpl();
this.policyConfiguration = DeviceConfigurationManager.getInstance().getDeviceManagementConfig()
.getPolicyConfiguration();
}
@Override
public Policy addPolicy(Policy policy) throws PolicyManagementException {
Policy resultantPolicy = policyManager.addPolicy(policy);
// try {
// delegator.delegate(resultantPolicy, resultantPolicy.getDevices());
// } catch (PolicyDelegationException e) {
// throw new PolicyManagementException("Error occurred while delegating policy operation to the devices", e);
// }
if (policyConfiguration.getCacheEnable()) {
PolicyCacheManagerImpl.getInstance().rePopulateCache();
}
@ -84,11 +72,6 @@ public class PolicyAdministratorPointImpl implements PolicyAdministratorPoint {
@Override
public Policy updatePolicy(Policy policy) throws PolicyManagementException {
Policy resultantPolicy = policyManager.updatePolicy(policy);
// try {
// delegator.delegate(resultantPolicy, resultantPolicy.getDevices());
// } catch (PolicyDelegationException e) {
// throw new PolicyManagementException("Error occurred while delegating policy operation to the devices", e);
// }
if (policyConfiguration.getCacheEnable()) {
PolicyCacheManagerImpl.getInstance().rePopulateCache();
}
@ -190,7 +173,6 @@ public class PolicyAdministratorPointImpl implements PolicyAdministratorPoint {
}
}
}
} catch (TaskException e) {
String msg = "Error occurred while creating the policy delegation task for tenant " +
PrivilegedCarbonContext.
@ -198,42 +180,6 @@ public class PolicyAdministratorPointImpl implements PolicyAdministratorPoint {
log.error(msg, e);
throw new PolicyManagementException(msg, e);
}
// List<DeviceType> deviceTypes = policyManager.applyChangesMadeToPolicies();
//
// if(log.isDebugEnabled()) {
// log.debug("Number of device types which policies are changed .......... : " + deviceTypes.size() );
// }
//
// if (!deviceTypes.isEmpty()) {
//
//
// DeviceManagementProviderService service = PolicyManagementDataHolder.getInstance()
// .getDeviceManagementService();
// List<Device> devices = new ArrayList<>();
// for (DeviceType deviceType : deviceTypes) {
// try {
// devices.addAll(service.getAllDevices(deviceType.getName()));
// } catch (DeviceManagementException e) {
// throw new PolicyManagementException("Error occurred while taking the devices", e);
// }
// }
// HashMap<Integer, Integer> deviceIdPolicy = policyManager.getAppliedPolicyIdsDeviceIds();
// List<Device> toBeNotified = new ArrayList<>();
//
// for (Device device : devices) {
// if (deviceIdPolicy.containsKey(device.getId())) {
// toBeNotified.add(device);
// }
// }
// if (!toBeNotified.isEmpty()) {
//
// // ExecutorService executorService = getExecutor();
// // PolicyEnforcementDelegator enforcementDelegator = new PolicyEnforcementDelegatorImpl(toBeNotified);
//// Thread thread = new Thread(new PolicyEnforcementDelegatorImpl(toBeNotified));
//// thread.start();
// }
// }
}
@Override

@ -63,7 +63,7 @@ public class PolicyFilterImpl implements PolicyFilter {
}
}
List<Policy> temp = new ArrayList<Policy>();
List<Policy> temp = new ArrayList<>();
for (Policy policy : policies) {
if (policy.isActive()) {
temp.add(policy);

@ -18,8 +18,6 @@
package org.wso2.carbon.policy.mgt.core.mgt.bean;
import org.wso2.carbon.device.mgt.common.policy.mgt.Policy;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import java.util.List;

@ -32,7 +32,6 @@ import org.wso2.carbon.device.mgt.common.policy.mgt.Policy;
import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager;
import org.wso2.carbon.device.mgt.common.policy.mgt.ProfileFeature;
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceData;
import org.wso2.carbon.device.mgt.common.policy.mgt.ProfileFeature;
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceFeature;
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.NonComplianceData;
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException;
@ -268,14 +267,20 @@ public class MonitoringManagerImpl implements MonitoringManager {
int enrollmentId;
for (Device device : devices) {
enrollmentId = device.getEnrolmentInfo().getId();
if (persistedComplianceData.containsKey(enrollmentId)) {
notifiableDeviceEnrollments.put(enrollmentId, device);
} else if (appliedPolicyIds.containsKey(enrollmentId)){
PolicyDeviceWrapper policyDeviceWrapper = new PolicyDeviceWrapper();
policyDeviceWrapper.setDeviceId(device.getId());
policyDeviceWrapper.setEnrolmentId(device.getEnrolmentInfo().getId());
policyDeviceWrapper.setPolicyId(appliedPolicyIds.get(enrollmentId));
firstTimeComplianceData.add(policyDeviceWrapper);
/*
When a policy has applied to the device, and the first monitoring operation runs on the policy, then it
is considered as a compliance policy and adds monitoring operation on the applied policy.
If the device has identified the applied policy as either compliance or non-compliance policy then
adds monitoring operation on the applied policy.
.*/
if (appliedPolicyIds.containsKey(enrollmentId)) {
if (!persistedComplianceData.containsKey(enrollmentId)) {
PolicyDeviceWrapper policyDeviceWrapper = new PolicyDeviceWrapper();
policyDeviceWrapper.setDeviceId(device.getId());
policyDeviceWrapper.setEnrolmentId(device.getEnrolmentInfo().getId());
policyDeviceWrapper.setPolicyId(appliedPolicyIds.get(enrollmentId));
firstTimeComplianceData.add(policyDeviceWrapper);
}
notifiableDeviceEnrollments.put(enrollmentId, device);
}
}

@ -241,9 +241,9 @@ public class PolicyManagerImpl implements PolicyManager {
policy.getProfile().setUpdatedDate(currentTimestamp);
policy.setPriorityId(previousPolicy.getPriorityId());
policy.setPolicyPayloadVersion(previousPolicy.getPolicyPayloadVersion());
Policy updatedPolicy = policyDAO.updatePolicy(policy);
profileDAO.updateProfile(policy.getProfile());
policyDAO.updatePolicy(policy);
profileDAO.updateProfile(policy.getProfile());
featureDAO.updateProfileFeatures(existingFeaturesList, profileId);
if (!newFeaturesList.isEmpty()) {
featureDAO.addProfileFeatures(newFeaturesList, profileId);
@ -646,8 +646,8 @@ public class PolicyManagerImpl implements PolicyManager {
@Override
public void inactivatePolicy(int policyId) throws PolicyManagementException {
Policy policy = this.getPolicy(policyId);
try {
Policy policy = this.getPolicy(policyId);
PolicyManagementDAOFactory.beginTransaction();
policyDAO.inactivatePolicy(policyId);
policyDAO.recordUpdatedPolicy(policy);

@ -22,8 +22,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.policy.mgt.Profile;
import org.wso2.carbon.device.mgt.common.policy.mgt.ProfileFeature;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.dao.DeviceTypeDAO;
import org.wso2.carbon.policy.mgt.common.ProfileManagementException;
import org.wso2.carbon.policy.mgt.core.dao.FeatureDAO;
import org.wso2.carbon.policy.mgt.core.dao.FeatureManagerDAOException;
@ -41,17 +39,13 @@ import java.util.List;
public class ProfileManagerImpl implements ProfileManager {
private static Log log = LogFactory.getLog(ProfileManagerImpl.class);
private static final Log log = LogFactory.getLog(ProfileManagerImpl.class);
private ProfileDAO profileDAO;
private FeatureDAO featureDAO;
// private DeviceDAO deviceDAO;
private DeviceTypeDAO deviceTypeDAO;
public ProfileManagerImpl() {
profileDAO = PolicyManagementDAOFactory.getProfileDAO();
featureDAO = PolicyManagementDAOFactory.getFeatureDAO();
// deviceDAO = DeviceManagementDAOFactory.getDeviceDAO();
deviceTypeDAO = DeviceManagementDAOFactory.getDeviceTypeDAO();
}
@Override
@ -68,19 +62,21 @@ public class ProfileManagerImpl implements ProfileManager {
PolicyManagementDAOFactory.commitTransaction();
} catch (ProfileManagerDAOException e) {
PolicyManagementDAOFactory.rollbackTransaction();
throw new ProfileManagementException("Error occurred while adding the profile (" +
profile.getProfileName() + ")", e);
String msg = "Error occurred while adding the profile (" + profile.getProfileName() + ")";
log.error(msg, e);
throw new ProfileManagementException(msg, e);
} catch (FeatureManagerDAOException e) {
PolicyManagementDAOFactory.rollbackTransaction();
throw new ProfileManagementException("Error occurred while adding the profile features (" +
profile.getProfileName() + ")", e);
String msg = "Error occurred while adding the profile features (" + profile.getProfileName() + ")";
log.error(msg, e);
throw new ProfileManagementException(msg, e);
} catch (PolicyManagerDAOException e) {
throw new ProfileManagementException("Error occurred while adding the profile (" +
profile.getProfileName() + ") to the database", e);
String msg = "Error occurred while adding the profile (" + profile.getProfileName() + ") to the database";
log.error(msg, e);
throw new ProfileManagementException(msg, e);
} finally {
PolicyManagementDAOFactory.closeConnection();
}
return profile;
}
@ -115,7 +111,7 @@ public class ProfileManagerImpl implements ProfileManager {
@Override
public boolean deleteProfile(Profile profile) throws ProfileManagementException {
boolean bool = true;
boolean bool;
try {
PolicyManagementDAOFactory.beginTransaction();
featureDAO.deleteFeaturesOfProfile(profile);
@ -173,7 +169,7 @@ public class ProfileManagerImpl implements ProfileManager {
for (Profile profile : profileList) {
List<ProfileFeature> list = new ArrayList<ProfileFeature>();
List<ProfileFeature> list = new ArrayList<>();
for (ProfileFeature profileFeature : featureList) {
if (profile.getProfileId() == profileFeature.getProfileId()) {
list.add(profileFeature);
@ -204,7 +200,7 @@ public class ProfileManagerImpl implements ProfileManager {
featureList = featureDAO.getAllProfileFeatures();
for (Profile profile : profileList) {
List<ProfileFeature> profileFeatureList = new ArrayList<ProfileFeature>();
List<ProfileFeature> profileFeatureList = new ArrayList<>();
for (ProfileFeature profileFeature : featureList) {
if (profile.getProfileId() == profileFeature.getProfileId()) {
profileFeatureList.add(profileFeature);
@ -224,5 +220,4 @@ public class ProfileManagerImpl implements ProfileManager {
}
return profileList;
}
}

@ -38,7 +38,7 @@ import java.util.Map;
public class TaskScheduleServiceImpl implements TaskScheduleService {
private static Log log = LogFactory.getLog(TaskScheduleServiceImpl.class);
private static final Log log = LogFactory.getLog(TaskScheduleServiceImpl.class);
private PolicyConfiguration policyConfiguration;

@ -40,6 +40,7 @@ public final class PolicyManagementConstants {
public static final String DEVICE_CONFIG_XML_NAME = "cdm-config.xml";
public static final String ANY = "ANY";
public static final String POLICY_BUNDLE = "POLICY_BUNDLE";
public static final String MONITOR_POLICY_BUNDLE = "MONITOR_POLICY_BUNDLE";
public static final String TENANT_ID = "TENANT_ID";

Loading…
Cancel
Save