mirror of
https://repository.entgra.net/community/device-mgt-core.git
synced 2025-10-06 02:01:45 +00:00
Implement scheduled application install/uninstall task
Fixes entgra/product-iots#160
This commit is contained in:
parent
03e28c3eb9
commit
c9f12d47cb
@ -21,7 +21,6 @@ package org.wso2.carbon.device.application.mgt.common;
|
|||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import io.swagger.annotations.ApiModel;
|
import io.swagger.annotations.ApiModel;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import org.wso2.carbon.device.application.mgt.common.ErrorListItem;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -39,6 +38,14 @@ public class ErrorResponse {
|
|||||||
private String moreInfo = null;
|
private String moreInfo = null;
|
||||||
private List<ErrorListItem> errorItems = new ArrayList<>();
|
private List<ErrorListItem> errorItems = new ArrayList<>();
|
||||||
|
|
||||||
|
public ErrorResponse() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ErrorResponse(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
@JsonProperty(value = "code")
|
@JsonProperty(value = "code")
|
||||||
@ApiModelProperty(required = true, value = "")
|
@ApiModelProperty(required = true, value = "")
|
||||||
public Integer getCode() {
|
public Integer getCode() {
|
||||||
|
|||||||
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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.application.mgt.common;
|
||||||
|
|
||||||
|
public enum ExecutionStatus {
|
||||||
|
PENDING, EXECUTED, FAILED
|
||||||
|
}
|
||||||
@ -17,6 +17,6 @@
|
|||||||
|
|
||||||
package org.wso2.carbon.device.application.mgt.common;
|
package org.wso2.carbon.device.application.mgt.common;
|
||||||
|
|
||||||
public enum SubsciptionType {
|
public enum SubscriptionType {
|
||||||
USER, ROLE, GROUP, DEVICE
|
USER, ROLE, GROUP, DEVICE
|
||||||
}
|
}
|
||||||
@ -0,0 +1,172 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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.application.mgt.common.dto;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.ExecutionStatus;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.SubscriptionType;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a DTO for AP_SCHEDULED_SUBSCRIPTION table
|
||||||
|
*/
|
||||||
|
public class ScheduledSubscriptionDTO {
|
||||||
|
/**
|
||||||
|
* Generated ID of the subscription.
|
||||||
|
*/
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the task which is related to the subscription.
|
||||||
|
*
|
||||||
|
* Task name is a generated field and in the following pattern:
|
||||||
|
* {@code <SUBSCRIPTION-TYPE>_<ACTION>_<HASH-VALUE>}
|
||||||
|
* {@code SUBSCRIPTION-TYPE} - {@see {@linkplain SubscriptionType}}
|
||||||
|
* {@code ACTION} - {@see {@linkplain org.wso2.carbon.device.application.mgt.common.SubAction}
|
||||||
|
* {@code HASH-VALUE} - this is a hash value of the combination of application uuid and the subscriber list.
|
||||||
|
*
|
||||||
|
* Example: {@code DEVICE_INSTALL_e593e00e8ef55efc764295b6aa9ad56b}
|
||||||
|
*/
|
||||||
|
private String taskName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UUID of the application release which is subscribed to.
|
||||||
|
* {@see {@link org.wso2.carbon.device.application.mgt.common.response.ApplicationRelease}}
|
||||||
|
*/
|
||||||
|
private String applicationUUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of subscribers for the application release. The type of the list depends on the subscription type.
|
||||||
|
* {@see {@link SubscriptionType}}. If the subscription type is {@code SubscriptionType.DEVICE} the type will be
|
||||||
|
* {@link org.wso2.carbon.device.mgt.common.DeviceIdentifier} and if not the type will be {@link String}.
|
||||||
|
*/
|
||||||
|
private List<?> subscriberList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Status of the subscription. {@see {@link ExecutionStatus}}
|
||||||
|
*/
|
||||||
|
private ExecutionStatus status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scheduled time of subscription.
|
||||||
|
*/
|
||||||
|
private LocalDateTime scheduledAt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Username of the scheduler.
|
||||||
|
*/
|
||||||
|
private String scheduledBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the subscription is marked as deleted or not.
|
||||||
|
* {@code true} means that the related task is removed from the {@link org.wso2.carbon.ntask.core.TaskManager}.
|
||||||
|
*/
|
||||||
|
private boolean deleted;
|
||||||
|
|
||||||
|
public ScheduledSubscriptionDTO() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScheduledSubscriptionDTO(String taskName, String applicationUUID, LocalDateTime scheduledAt,
|
||||||
|
List<?> subscriberList, String scheduledBy) {
|
||||||
|
this.taskName = taskName;
|
||||||
|
this.applicationUUID = applicationUUID;
|
||||||
|
this.scheduledAt = scheduledAt;
|
||||||
|
this.subscriberList = subscriberList;
|
||||||
|
this.scheduledBy = scheduledBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTaskName() {
|
||||||
|
return taskName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskName(String taskName) {
|
||||||
|
this.taskName = taskName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApplicationUUID() {
|
||||||
|
return applicationUUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApplicationUUID(String applicationUUID) {
|
||||||
|
this.applicationUUID = applicationUUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<?> getSubscriberList() {
|
||||||
|
return subscriberList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubscriberList(List<?> subscriberList) {
|
||||||
|
this.subscriberList = subscriberList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecutionStatus getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(ExecutionStatus status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getScheduledAt() {
|
||||||
|
return scheduledAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScheduledAt(LocalDateTime scheduledAt) {
|
||||||
|
this.scheduledAt = scheduledAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getScheduledBy() {
|
||||||
|
return scheduledBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScheduledBy(String scheduledBy) {
|
||||||
|
this.scheduledBy = scheduledBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the string representation of the subscriber list.
|
||||||
|
*/
|
||||||
|
public String getSubscribersString() {
|
||||||
|
if (this.taskName.startsWith(SubscriptionType.DEVICE.toString())) {
|
||||||
|
return new Gson().toJson(this.subscriberList);
|
||||||
|
} else {
|
||||||
|
return this.subscriberList.stream().map(String.class::cast).collect(Collectors.joining(","));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDeleted() {
|
||||||
|
return deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeleted(boolean deleted) {
|
||||||
|
this.deleted = deleted;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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.application.mgt.common.exception;
|
||||||
|
|
||||||
|
public class SubscriptionManagementException extends Exception {
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
public SubscriptionManagementException(String message, Throwable throwable) {
|
||||||
|
super(message, throwable);
|
||||||
|
setMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubscriptionManagementException(String message) {
|
||||||
|
super(message);
|
||||||
|
setMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubscriptionManagementException() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -19,7 +19,10 @@
|
|||||||
package org.wso2.carbon.device.application.mgt.common.services;
|
package org.wso2.carbon.device.application.mgt.common.services;
|
||||||
|
|
||||||
import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponse;
|
import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponse;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.ExecutionStatus;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.dto.ScheduledSubscriptionDTO;
|
||||||
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
|
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.exception.SubscriptionManagementException;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -27,6 +30,57 @@ import java.util.List;
|
|||||||
* This interface manages all the operations related with ApplicationDTO Subscription.
|
* This interface manages all the operations related with ApplicationDTO Subscription.
|
||||||
*/
|
*/
|
||||||
public interface SubscriptionManager {
|
public interface SubscriptionManager {
|
||||||
|
/**
|
||||||
|
* Performs bulk subscription operation for a given application and a subscriber list.
|
||||||
|
*
|
||||||
|
* @param applicationUUID UUID of the application to subscribe/unsubscribe
|
||||||
|
* @param params list of subscribers. This list can be of either
|
||||||
|
* {@link org.wso2.carbon.device.mgt.common.DeviceIdentifier} if {@param subType} is equal
|
||||||
|
* to DEVICE or
|
||||||
|
* {@link String} if {@param subType} is USER, ROLE or GROUP
|
||||||
|
* @param subType subscription type. E.g. <code>DEVICE, USER, ROLE, GROUP</code> {@see {
|
||||||
|
* @param action subscription action. E.g. <code>INSTALL/UNINSTALL</code> {@see {
|
||||||
|
* @param <T> generic type of the method.
|
||||||
|
* @return {@link ApplicationInstallResponse}
|
||||||
|
* @throws ApplicationManagementException if error occurs when subscribing to the given application
|
||||||
|
* @link org.wso2.carbon.device.application.mgt.common.SubscriptionType}}
|
||||||
|
* @link org.wso2.carbon.device.application.mgt.common.SubAction}}
|
||||||
|
*/
|
||||||
<T> ApplicationInstallResponse performBulkAppOperation(String applicationUUID, List<T> params, String subType,
|
<T> ApplicationInstallResponse performBulkAppOperation(String applicationUUID, List<T> params, String subType,
|
||||||
String action) throws ApplicationManagementException;
|
String action) throws ApplicationManagementException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an entry related to the scheduled task in the database.
|
||||||
|
*
|
||||||
|
* @param subscriptionDTO {@link ScheduledSubscriptionDTO} with details of the subscription
|
||||||
|
* @throws SubscriptionManagementException if unable to create/update entry for the scheduled task
|
||||||
|
*/
|
||||||
|
void createScheduledSubscription(ScheduledSubscriptionDTO subscriptionDTO) throws SubscriptionManagementException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark already executed, misfired and failed tasks as deleted.
|
||||||
|
*
|
||||||
|
* @return deleted list of subscriptions
|
||||||
|
* @throws SubscriptionManagementException if error occurred while cleaning up subscriptions.
|
||||||
|
*/
|
||||||
|
List<ScheduledSubscriptionDTO> cleanScheduledSubscriptions() throws SubscriptionManagementException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the subscription entry which is pending by task name. At a given time, there should be only a single
|
||||||
|
* entry in the status {@code PENDING} and not marked as deleted.
|
||||||
|
*
|
||||||
|
* @param taskName name of the task to retrieve
|
||||||
|
* @return {@link ScheduledSubscriptionDTO}
|
||||||
|
* @throws SubscriptionManagementException if error occurred while retrieving the subscription details
|
||||||
|
*/
|
||||||
|
ScheduledSubscriptionDTO getPendingScheduledSubscription(String taskName) throws SubscriptionManagementException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the status of a subscription.
|
||||||
|
*
|
||||||
|
* @param id id of the subscription
|
||||||
|
* @param status new status of the subscription. {@see {@link ExecutionStatus}}
|
||||||
|
* @throws SubscriptionManagementException if error occurred while updating the status of the subscription
|
||||||
|
*/
|
||||||
|
void updateScheduledSubscriptionStatus(int id, ExecutionStatus status) throws SubscriptionManagementException;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,7 +60,7 @@
|
|||||||
org.w3c.dom,
|
org.w3c.dom,
|
||||||
org.json,
|
org.json,
|
||||||
javax.sql,
|
javax.sql,
|
||||||
com.google.gson,
|
com.google.gson.*,
|
||||||
javax.naming,
|
javax.naming,
|
||||||
javax.xml.bind.annotation,
|
javax.xml.bind.annotation,
|
||||||
javax.xml.bind,
|
javax.xml.bind,
|
||||||
@ -69,6 +69,8 @@
|
|||||||
org.wso2.carbon.device.mgt.common.*,
|
org.wso2.carbon.device.mgt.common.*,
|
||||||
org.wso2.carbon.user.core.*,
|
org.wso2.carbon.user.core.*,
|
||||||
org.wso2.carbon.user.api.*,
|
org.wso2.carbon.user.api.*,
|
||||||
|
org.wso2.carbon.ntask.*,
|
||||||
|
org.quartz.*,
|
||||||
org.wso2.carbon.ndatasource.core,
|
org.wso2.carbon.ndatasource.core,
|
||||||
org.wso2.carbon,
|
org.wso2.carbon,
|
||||||
org.xml.sax,
|
org.xml.sax,
|
||||||
|
|||||||
@ -16,12 +16,33 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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.application.mgt.core.dao;
|
package org.wso2.carbon.device.application.mgt.core.dao;
|
||||||
|
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.ExecutionStatus;
|
||||||
import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO;
|
import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO;
|
||||||
import org.wso2.carbon.device.application.mgt.common.dto.DeviceSubscriptionDTO;
|
import org.wso2.carbon.device.application.mgt.common.dto.DeviceSubscriptionDTO;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.dto.ScheduledSubscriptionDTO;
|
||||||
import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException;
|
import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -85,4 +106,68 @@ public interface SubscriptionDAO {
|
|||||||
boolean updateDeviceSubStatus(int deviceId, List<Integer> deviceSubIds, String status, int tenantcId)
|
boolean updateDeviceSubStatus(int deviceId, List<Integer> deviceSubIds, String status, int tenantcId)
|
||||||
throws ApplicationManagementDAOException;
|
throws ApplicationManagementDAOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a scheduled subscription entry in the data store.
|
||||||
|
*
|
||||||
|
* @param subscriptionDTO {@link ScheduledSubscriptionDTO} which contains the details of the subscription
|
||||||
|
* @throws ApplicationManagementDAOException if error occurred while creating an entry in the data store.
|
||||||
|
*/
|
||||||
|
boolean createScheduledSubscription(ScheduledSubscriptionDTO subscriptionDTO) throws ApplicationManagementDAOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the existing entry of a scheduled subscription.
|
||||||
|
*
|
||||||
|
* @param id id of the existing subscription
|
||||||
|
* @param scheduledAt scheduled time
|
||||||
|
* @param scheduledBy username of the user who scheduled the subscription
|
||||||
|
* @throws ApplicationManagementDAOException if error occurred while updating the entry
|
||||||
|
*/
|
||||||
|
boolean updateScheduledSubscription(int id, LocalDateTime scheduledAt, String scheduledBy)
|
||||||
|
throws ApplicationManagementDAOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks A list of given scheduled subscription as deleted.
|
||||||
|
*
|
||||||
|
* @param subscriptionIdList list of ids of the subscriptions to delete
|
||||||
|
* @throws ApplicationManagementDAOException if error occurred while deleting the subscription
|
||||||
|
*/
|
||||||
|
boolean deleteScheduledSubscription(List<Integer> subscriptionIdList) throws ApplicationManagementDAOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the status of an existing subscription.
|
||||||
|
*
|
||||||
|
* @param id id of the existing subscription
|
||||||
|
* @param status changed status {@see {@link ExecutionStatus}}
|
||||||
|
* @throws ApplicationManagementDAOException if error occurs while changing the status of the subscription
|
||||||
|
*/
|
||||||
|
boolean updateScheduledSubscriptionStatus(int id, ExecutionStatus status) throws ApplicationManagementDAOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a list of scheduled subscriptions of a given state
|
||||||
|
*
|
||||||
|
* @param status status of the subscriptions
|
||||||
|
* @param deleted is the subscription marked as deleted
|
||||||
|
* @return list of {@link ScheduledSubscriptionDTO}
|
||||||
|
* @throws ApplicationManagementDAOException if error occurred while retrieving the subscriptions
|
||||||
|
*/
|
||||||
|
List<ScheduledSubscriptionDTO> getScheduledSubscriptionByStatus(ExecutionStatus status, boolean deleted)
|
||||||
|
throws ApplicationManagementDAOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a list of subscriptions that are not executed on the scheduled time.
|
||||||
|
*
|
||||||
|
* @return list of {@link ScheduledSubscriptionDTO}
|
||||||
|
* @throws ApplicationManagementDAOException if error occurred while retrieving the subscriptions.
|
||||||
|
*/
|
||||||
|
List<ScheduledSubscriptionDTO> getNonExecutedSubscriptions() throws ApplicationManagementDAOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a subscription by taskName which is in the <code>ExecutionStatus.PENDING</code> state.
|
||||||
|
*
|
||||||
|
* @param taskName name of the task to retrieve.
|
||||||
|
* @return {@link ScheduledSubscriptionDTO}
|
||||||
|
* @throws ApplicationManagementDAOException if error occurred while retrieving the subscription
|
||||||
|
*/
|
||||||
|
ScheduledSubscriptionDTO getPendingScheduledSubscriptionByTaskName(String taskName)
|
||||||
|
throws ApplicationManagementDAOException;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,25 +15,48 @@
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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.application.mgt.core.dao.impl.subscription;
|
package org.wso2.carbon.device.application.mgt.core.dao.impl.subscription;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.ExecutionStatus;
|
||||||
import org.wso2.carbon.device.application.mgt.common.SubAction;
|
import org.wso2.carbon.device.application.mgt.common.SubAction;
|
||||||
import org.wso2.carbon.device.application.mgt.common.SubsciptionType;
|
import org.wso2.carbon.device.application.mgt.common.SubscriptionType;
|
||||||
import org.wso2.carbon.device.application.mgt.common.dto.DeviceSubscriptionDTO;
|
import org.wso2.carbon.device.application.mgt.common.dto.DeviceSubscriptionDTO;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.dto.ScheduledSubscriptionDTO;
|
||||||
import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException;
|
import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException;
|
||||||
import org.wso2.carbon.device.application.mgt.core.dao.SubscriptionDAO;
|
import org.wso2.carbon.device.application.mgt.core.dao.SubscriptionDAO;
|
||||||
import org.wso2.carbon.device.application.mgt.core.util.DAOUtil;
|
|
||||||
import org.wso2.carbon.device.application.mgt.core.dao.impl.AbstractDAOImpl;
|
import org.wso2.carbon.device.application.mgt.core.dao.impl.AbstractDAOImpl;
|
||||||
import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException;
|
import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException;
|
||||||
|
import org.wso2.carbon.device.application.mgt.core.exception.UnexpectedServerErrorException;
|
||||||
|
import org.wso2.carbon.device.application.mgt.core.util.DAOUtil;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -579,11 +602,11 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
|
|||||||
try {
|
try {
|
||||||
Connection conn = this.getDBConnection();
|
Connection conn = this.getDBConnection();
|
||||||
String sql = "UPDATE ";
|
String sql = "UPDATE ";
|
||||||
if (SubsciptionType.USER.toString().equalsIgnoreCase(subType)) {
|
if (SubscriptionType.USER.toString().equalsIgnoreCase(subType)) {
|
||||||
sql += "AP_USER_SUBSCRIPTION SET ";
|
sql += "AP_USER_SUBSCRIPTION SET ";
|
||||||
} else if (SubsciptionType.ROLE.toString().equalsIgnoreCase(subType)) {
|
} else if (SubscriptionType.ROLE.toString().equalsIgnoreCase(subType)) {
|
||||||
sql += "AP_ROLE_SUBSCRIPTION SET ";
|
sql += "AP_ROLE_SUBSCRIPTION SET ";
|
||||||
} else if (SubsciptionType.GROUP.toString().equalsIgnoreCase(subType)) {
|
} else if (SubscriptionType.GROUP.toString().equalsIgnoreCase(subType)) {
|
||||||
sql += "AP_GROUP_SUBSCRIPTION SET ";
|
sql += "AP_GROUP_SUBSCRIPTION SET ";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -593,11 +616,11 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
|
|||||||
sql += "SUBSCRIBED_BY = ?, SUBSCRIBED_TIMESTAMP = ? ";
|
sql += "SUBSCRIBED_BY = ?, SUBSCRIBED_TIMESTAMP = ? ";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SubsciptionType.USER.toString().equalsIgnoreCase(subType)) {
|
if (SubscriptionType.USER.toString().equalsIgnoreCase(subType)) {
|
||||||
sql += "WHERE USER_NAME = ? ";
|
sql += "WHERE USER_NAME = ? ";
|
||||||
} else if (SubsciptionType.ROLE.toString().equalsIgnoreCase(subType)) {
|
} else if (SubscriptionType.ROLE.toString().equalsIgnoreCase(subType)) {
|
||||||
sql += "WHERE ROLE_NAME = ? ";
|
sql += "WHERE ROLE_NAME = ? ";
|
||||||
} else if (SubsciptionType.GROUP.toString().equalsIgnoreCase(subType)) {
|
} else if (SubscriptionType.GROUP.toString().equalsIgnoreCase(subType)) {
|
||||||
sql += "WHERE GROUP_NAME = ? ";
|
sql += "WHERE GROUP_NAME = ? ";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -696,4 +719,240 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
|
|||||||
throw new ApplicationManagementDAOException(msg, e);
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean createScheduledSubscription(ScheduledSubscriptionDTO subscriptionDTO)
|
||||||
|
throws ApplicationManagementDAOException {
|
||||||
|
String sql = "INSERT INTO "
|
||||||
|
+ "AP_SCHEDULED_SUBSCRIPTION ("
|
||||||
|
+ "TASK_NAME, "
|
||||||
|
+ "APPLICATION_UUID, "
|
||||||
|
+ "SUBSCRIBER_LIST, "
|
||||||
|
+ "STATUS, "
|
||||||
|
+ "SCHEDULED_AT, "
|
||||||
|
+ "SCHEDULED_TIMESTAMP,"
|
||||||
|
+ "SCHEDULED_BY,"
|
||||||
|
+ "DELETED) "
|
||||||
|
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
|
||||||
|
try {
|
||||||
|
Connection conn = this.getDBConnection();
|
||||||
|
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
stmt.setString(1, subscriptionDTO.getTaskName());
|
||||||
|
stmt.setString(2, subscriptionDTO.getApplicationUUID());
|
||||||
|
stmt.setString(3, subscriptionDTO.getSubscribersString());
|
||||||
|
stmt.setString(4, ExecutionStatus.PENDING.toString());
|
||||||
|
stmt.setTimestamp(5, Timestamp.valueOf(subscriptionDTO.getScheduledAt()));
|
||||||
|
stmt.setTimestamp(6, new Timestamp(calendar.getTime().getTime()));
|
||||||
|
stmt.setString(7, subscriptionDTO.getScheduledBy());
|
||||||
|
stmt.setBoolean(8, false);
|
||||||
|
return stmt.executeUpdate() > 0;
|
||||||
|
}
|
||||||
|
} catch (DBConnectionException e) {
|
||||||
|
String msg = "Error occurred while obtaining the DB connection to insert the subscription status of the "
|
||||||
|
+ "scheduled subscription.";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
String msg = "Error occurred when processing SQL to insert the " + "subscription status of the scheduled "
|
||||||
|
+ "subscription.";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateScheduledSubscription(int id, LocalDateTime scheduledAt, String scheduledBy)
|
||||||
|
throws ApplicationManagementDAOException {
|
||||||
|
String sql = "UPDATE AP_SCHEDULED_SUBSCRIPTION AP "
|
||||||
|
+ "SET "
|
||||||
|
+ "AP.SCHEDULED_AT = ?, "
|
||||||
|
+ "AP.SCHEDULED_BY = ?, "
|
||||||
|
+ "AP.SCHEDULED_TIMESTAMP = ? "
|
||||||
|
+ "WHERE AP.ID = ?";
|
||||||
|
try {
|
||||||
|
Connection conn = this.getDBConnection();
|
||||||
|
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
stmt.setTimestamp(1, Timestamp.valueOf(scheduledAt));
|
||||||
|
stmt.setString(2, scheduledBy);
|
||||||
|
stmt.setTimestamp(3, new Timestamp(calendar.getTime().getTime()));
|
||||||
|
stmt.setInt(4, id);
|
||||||
|
return stmt.executeUpdate() > 0;
|
||||||
|
}
|
||||||
|
} catch (DBConnectionException e) {
|
||||||
|
String msg =
|
||||||
|
"Error occurred while obtaining the DB connection to update the existing entry of the scheduled "
|
||||||
|
+ "subscription.";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
String msg = "Error occurred when processing SQL to update the existing entry of the scheduled subscription.";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteScheduledSubscription(List<Integer> subscriptionIdList) throws ApplicationManagementDAOException {
|
||||||
|
String sql = "UPDATE AP_SCHEDULED_SUBSCRIPTION AP "
|
||||||
|
+ "SET AP.DELETED = ? "
|
||||||
|
+ "WHERE AP.ID = ?";
|
||||||
|
try {
|
||||||
|
Connection conn = this.getDBConnection();
|
||||||
|
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
for (Integer id: subscriptionIdList) {
|
||||||
|
stmt.setBoolean(1, true);
|
||||||
|
stmt.setInt(2, id);
|
||||||
|
stmt.addBatch();
|
||||||
|
}
|
||||||
|
int[] results = stmt.executeBatch();
|
||||||
|
return Arrays.stream(results).allMatch(r -> r > 0);
|
||||||
|
}
|
||||||
|
} catch (DBConnectionException e) {
|
||||||
|
String msg =
|
||||||
|
"Error occurred while obtaining the DB connection to delete the existing entry of the scheduled "
|
||||||
|
+ "subscription.";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
String msg = "Error occurred when processing SQL to delete the existing entry of the scheduled subscription.";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateScheduledSubscriptionStatus(int id, ExecutionStatus status)
|
||||||
|
throws ApplicationManagementDAOException {
|
||||||
|
String sql = "UPDATE AP_SCHEDULED_SUBSCRIPTION AP "
|
||||||
|
+ "SET AP.STATUS = ? "
|
||||||
|
+ "WHERE AP.ID = ?";
|
||||||
|
try {
|
||||||
|
Connection conn = this.getDBConnection();
|
||||||
|
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setString(1, status.toString());
|
||||||
|
stmt.setInt(2, id);
|
||||||
|
return stmt.executeUpdate() > 0;
|
||||||
|
}
|
||||||
|
} catch (DBConnectionException e) {
|
||||||
|
String msg = "Error occurred while obtaining the DB connection to update the status of the scheduled "
|
||||||
|
+ "subscription.";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
String msg = "Error occurred when processing SQL to update the status of the scheduled subscription.";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ScheduledSubscriptionDTO> getScheduledSubscriptionByStatus(ExecutionStatus status, boolean deleted)
|
||||||
|
throws ApplicationManagementDAOException {
|
||||||
|
String sql = "SELECT "
|
||||||
|
+ "ID, "
|
||||||
|
+ "TASK_NAME, "
|
||||||
|
+ "APPLICATION_UUID, "
|
||||||
|
+ "SUBSCRIBER_LIST, "
|
||||||
|
+ "STATUS, "
|
||||||
|
+ "SCHEDULED_AT, "
|
||||||
|
+ "SCHEDULED_BY, "
|
||||||
|
+ "DELETED "
|
||||||
|
+ "FROM AP_SCHEDULED_SUBSCRIPTION "
|
||||||
|
+ "WHERE STATUS = ? AND DELETED = ?";
|
||||||
|
try {
|
||||||
|
Connection conn = this.getDBConnection();
|
||||||
|
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setString(1, status.toString());
|
||||||
|
stmt.setBoolean(2, deleted);
|
||||||
|
try (ResultSet rs = stmt.executeQuery()) {
|
||||||
|
return DAOUtil.loadScheduledSubscriptions(rs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (DBConnectionException e) {
|
||||||
|
String msg = "Error occurred while obtaining the DB connection to retrieve" + status.toString()
|
||||||
|
+ " subscriptions";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
String msg = "Error occurred when processing SQL to retrieve" + status.toString() + " subscriptions";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ScheduledSubscriptionDTO> getNonExecutedSubscriptions() throws ApplicationManagementDAOException {
|
||||||
|
String sql = "SELECT "
|
||||||
|
+ "ID, "
|
||||||
|
+ "TASK_NAME, "
|
||||||
|
+ "APPLICATION_UUID, "
|
||||||
|
+ "SUBSCRIBER_LIST, "
|
||||||
|
+ "STATUS, "
|
||||||
|
+ "SCHEDULED_AT, "
|
||||||
|
+ "SCHEDULED_BY, "
|
||||||
|
+ "DELETED "
|
||||||
|
+ "FROM AP_SCHEDULED_SUBSCRIPTION "
|
||||||
|
+ "WHERE STATUS = ? AND DELETED = ? AND SCHEDULED_AT < ?";
|
||||||
|
try {
|
||||||
|
Connection conn = this.getDBConnection();
|
||||||
|
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setString(1, ExecutionStatus.PENDING.toString());
|
||||||
|
stmt.setBoolean(2, false);
|
||||||
|
stmt.setTimestamp(3, new Timestamp(Calendar.getInstance().getTime().getTime()));
|
||||||
|
try (ResultSet rs = stmt.executeQuery()) {
|
||||||
|
return DAOUtil.loadScheduledSubscriptions(rs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (DBConnectionException e) {
|
||||||
|
String msg = "Error occurred while obtaining the DB connection to retrieve missed subscriptions";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
String msg = "Error occurred when processing SQL to retrieve missed subscriptions.";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScheduledSubscriptionDTO getPendingScheduledSubscriptionByTaskName(String taskName)
|
||||||
|
throws ApplicationManagementDAOException {
|
||||||
|
String sql = "SELECT "
|
||||||
|
+ "ID, "
|
||||||
|
+ "TASK_NAME, "
|
||||||
|
+ "APPLICATION_UUID, "
|
||||||
|
+ "SUBSCRIBER_LIST, "
|
||||||
|
+ "STATUS, "
|
||||||
|
+ "SCHEDULED_AT, "
|
||||||
|
+ "SCHEDULED_BY, "
|
||||||
|
+ "DELETED "
|
||||||
|
+ "FROM AP_SCHEDULED_SUBSCRIPTION "
|
||||||
|
+ "WHERE TASK_NAME = ? AND STATUS = ? AND DELETED = ?";
|
||||||
|
try {
|
||||||
|
Connection conn = this.getDBConnection();
|
||||||
|
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setString(1, taskName);
|
||||||
|
stmt.setString(2, ExecutionStatus.PENDING.toString());
|
||||||
|
stmt.setBoolean(3, false);
|
||||||
|
try (ResultSet rs = stmt.executeQuery()) {
|
||||||
|
return DAOUtil.loadScheduledSubscription(rs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (DBConnectionException e) {
|
||||||
|
String msg =
|
||||||
|
"Error occurred while obtaining the DB connection to retrieve pending subscriptions of " + taskName;
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
String msg = "Error occurred when processing SQL to retrieve pending subscriptions of " + taskName;
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
|
} catch (UnexpectedServerErrorException e) {
|
||||||
|
String msg = "More than one pending subscriptions exist for " + taskName;
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new ApplicationManagementDAOException(msg, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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.application.mgt.core.exception;
|
||||||
|
|
||||||
|
public class ApplicationOperationTaskException extends Exception {
|
||||||
|
|
||||||
|
public ApplicationOperationTaskException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApplicationOperationTaskException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -24,14 +24,17 @@ import org.wso2.carbon.context.PrivilegedCarbonContext;
|
|||||||
import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponse;
|
import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponse;
|
||||||
import org.wso2.carbon.device.application.mgt.common.ApplicationType;
|
import org.wso2.carbon.device.application.mgt.common.ApplicationType;
|
||||||
import org.wso2.carbon.device.application.mgt.common.DeviceTypes;
|
import org.wso2.carbon.device.application.mgt.common.DeviceTypes;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.ExecutionStatus;
|
||||||
import org.wso2.carbon.device.application.mgt.common.SubAction;
|
import org.wso2.carbon.device.application.mgt.common.SubAction;
|
||||||
import org.wso2.carbon.device.application.mgt.common.SubsciptionType;
|
import org.wso2.carbon.device.application.mgt.common.SubscriptionType;
|
||||||
import org.wso2.carbon.device.application.mgt.common.SubscribingDeviceIdHolder;
|
import org.wso2.carbon.device.application.mgt.common.SubscribingDeviceIdHolder;
|
||||||
import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO;
|
import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO;
|
||||||
import org.wso2.carbon.device.application.mgt.common.dto.DeviceSubscriptionDTO;
|
import org.wso2.carbon.device.application.mgt.common.dto.DeviceSubscriptionDTO;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.dto.ScheduledSubscriptionDTO;
|
||||||
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
|
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
|
||||||
import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException;
|
import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException;
|
||||||
import org.wso2.carbon.device.application.mgt.common.exception.LifecycleManagementException;
|
import org.wso2.carbon.device.application.mgt.common.exception.LifecycleManagementException;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.exception.SubscriptionManagementException;
|
||||||
import org.wso2.carbon.device.application.mgt.common.exception.TransactionManagementException;
|
import org.wso2.carbon.device.application.mgt.common.exception.TransactionManagementException;
|
||||||
import org.wso2.carbon.device.application.mgt.common.response.Application;
|
import org.wso2.carbon.device.application.mgt.common.response.Application;
|
||||||
import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager;
|
import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager;
|
||||||
@ -114,7 +117,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
|
|||||||
|
|
||||||
//todo validate users, groups and roles
|
//todo validate users, groups and roles
|
||||||
ApplicationDTO applicationDTO = getApplicationDTO(applicationUUID);
|
ApplicationDTO applicationDTO = getApplicationDTO(applicationUUID);
|
||||||
if (SubsciptionType.DEVICE.toString().equals(subType)) {
|
if (SubscriptionType.DEVICE.toString().equals(subType)) {
|
||||||
for (T param : params) {
|
for (T param : params) {
|
||||||
DeviceIdentifier deviceIdentifier = (DeviceIdentifier) param;
|
DeviceIdentifier deviceIdentifier = (DeviceIdentifier) param;
|
||||||
if (StringUtils.isEmpty(deviceIdentifier.getId()) || StringUtils
|
if (StringUtils.isEmpty(deviceIdentifier.getId()) || StringUtils
|
||||||
@ -136,19 +139,19 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
|
|||||||
}
|
}
|
||||||
devices.add(deviceManagementProviderService.getDevice(deviceIdentifier, false));
|
devices.add(deviceManagementProviderService.getDevice(deviceIdentifier, false));
|
||||||
}
|
}
|
||||||
} else if (SubsciptionType.USER.toString().equalsIgnoreCase(subType)) {
|
} else if (SubscriptionType.USER.toString().equalsIgnoreCase(subType)) {
|
||||||
for (T param : params) {
|
for (T param : params) {
|
||||||
String username = (String) param;
|
String username = (String) param;
|
||||||
subscribers.add(username);
|
subscribers.add(username);
|
||||||
devices.addAll(deviceManagementProviderService.getDevicesOfUser(username));
|
devices.addAll(deviceManagementProviderService.getDevicesOfUser(username));
|
||||||
}
|
}
|
||||||
} else if (SubsciptionType.ROLE.toString().equalsIgnoreCase(subType)) {
|
} else if (SubscriptionType.ROLE.toString().equalsIgnoreCase(subType)) {
|
||||||
for (T param : params) {
|
for (T param : params) {
|
||||||
String roleName = (String) param;
|
String roleName = (String) param;
|
||||||
subscribers.add(roleName);
|
subscribers.add(roleName);
|
||||||
devices.addAll(deviceManagementProviderService.getAllDevicesOfRole(roleName));
|
devices.addAll(deviceManagementProviderService.getAllDevicesOfRole(roleName));
|
||||||
}
|
}
|
||||||
} else if (SubsciptionType.GROUP.toString().equalsIgnoreCase(subType)) {
|
} else if (SubscriptionType.GROUP.toString().equalsIgnoreCase(subType)) {
|
||||||
for (T param : params) {
|
for (T param : params) {
|
||||||
String groupName = (String) param;
|
String groupName = (String) param;
|
||||||
subscribers.add(groupName);
|
subscribers.add(groupName);
|
||||||
@ -184,6 +187,125 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createScheduledSubscription(ScheduledSubscriptionDTO subscriptionDTO)
|
||||||
|
throws SubscriptionManagementException {
|
||||||
|
try {
|
||||||
|
ConnectionManagerUtil.beginDBTransaction();
|
||||||
|
ScheduledSubscriptionDTO existingEntry = subscriptionDAO.getPendingScheduledSubscriptionByTaskName(
|
||||||
|
subscriptionDTO.getTaskName());
|
||||||
|
boolean transactionStatus;
|
||||||
|
if (existingEntry == null) {
|
||||||
|
transactionStatus = subscriptionDAO.createScheduledSubscription(subscriptionDTO);
|
||||||
|
} else {
|
||||||
|
transactionStatus = subscriptionDAO.updateScheduledSubscription(existingEntry.getId(),
|
||||||
|
subscriptionDTO.getScheduledAt(), subscriptionDTO.getScheduledBy());
|
||||||
|
}
|
||||||
|
if (!transactionStatus) {
|
||||||
|
ConnectionManagerUtil.rollbackDBTransaction();
|
||||||
|
}
|
||||||
|
ConnectionManagerUtil.commitDBTransaction();
|
||||||
|
} catch (ApplicationManagementDAOException e) {
|
||||||
|
ConnectionManagerUtil.rollbackDBTransaction();
|
||||||
|
String msg = "Error occurred while creating the scheduled subscription entry.";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new SubscriptionManagementException(msg, e);
|
||||||
|
} catch (TransactionManagementException e) {
|
||||||
|
String msg = "Error occurred while executing database transaction";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new SubscriptionManagementException(msg, e);
|
||||||
|
} catch (DBConnectionException e) {
|
||||||
|
String msg = "Error occurred while observing the database connection to update subscription status.";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new SubscriptionManagementException(msg, e);
|
||||||
|
} finally {
|
||||||
|
ConnectionManagerUtil.closeDBConnection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ScheduledSubscriptionDTO> cleanScheduledSubscriptions() throws SubscriptionManagementException {
|
||||||
|
try {
|
||||||
|
// Cleaning up already executed, missed and failed tasks
|
||||||
|
ConnectionManagerUtil.beginDBTransaction();
|
||||||
|
List<ScheduledSubscriptionDTO> taskList = subscriptionDAO.getScheduledSubscriptionByStatus(
|
||||||
|
ExecutionStatus.EXECUTED, false);
|
||||||
|
taskList.addAll(subscriptionDAO.getNonExecutedSubscriptions());
|
||||||
|
taskList.addAll(subscriptionDAO.getScheduledSubscriptionByStatus(ExecutionStatus.FAILED, false));
|
||||||
|
List<Integer> tasksToClean = taskList.stream().map(ScheduledSubscriptionDTO::getId).collect(
|
||||||
|
Collectors.toList());
|
||||||
|
if (!subscriptionDAO.deleteScheduledSubscription(tasksToClean)) {
|
||||||
|
ConnectionManagerUtil.rollbackDBTransaction();
|
||||||
|
}
|
||||||
|
ConnectionManagerUtil.commitDBTransaction();
|
||||||
|
return taskList;
|
||||||
|
} catch (ApplicationManagementDAOException e) {
|
||||||
|
ConnectionManagerUtil.rollbackDBTransaction();
|
||||||
|
String msg = "Error occurred while cleaning up the old subscriptions.";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new SubscriptionManagementException(msg, e);
|
||||||
|
} catch (TransactionManagementException e) {
|
||||||
|
String msg = "Error occurred while executing database transaction";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new SubscriptionManagementException(msg, e);
|
||||||
|
} catch (DBConnectionException e) {
|
||||||
|
String msg = "Error occurred while retrieving the database connection";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new SubscriptionManagementException(msg, e);
|
||||||
|
} finally {
|
||||||
|
ConnectionManagerUtil.closeDBConnection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScheduledSubscriptionDTO getPendingScheduledSubscription(String taskName)
|
||||||
|
throws SubscriptionManagementException {
|
||||||
|
try {
|
||||||
|
ConnectionManagerUtil.openDBConnection();
|
||||||
|
return subscriptionDAO.getPendingScheduledSubscriptionByTaskName(taskName);
|
||||||
|
} catch (ApplicationManagementDAOException e) {
|
||||||
|
String msg = "Error occurred while retrieving subscription for task: " + taskName;
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new SubscriptionManagementException(msg, e);
|
||||||
|
} catch (DBConnectionException e) {
|
||||||
|
String msg = "Error occurred while retrieving the database connection";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new SubscriptionManagementException(msg, e);
|
||||||
|
} finally {
|
||||||
|
ConnectionManagerUtil.closeDBConnection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateScheduledSubscriptionStatus(int id, ExecutionStatus status)
|
||||||
|
throws SubscriptionManagementException {
|
||||||
|
try {
|
||||||
|
ConnectionManagerUtil.beginDBTransaction();
|
||||||
|
if (!subscriptionDAO.updateScheduledSubscriptionStatus(id, status)) {
|
||||||
|
ConnectionManagerUtil.rollbackDBTransaction();
|
||||||
|
String msg = "Unable to update the status of the subscription: " + id;
|
||||||
|
log.error(msg);
|
||||||
|
throw new SubscriptionManagementException(msg);
|
||||||
|
}
|
||||||
|
ConnectionManagerUtil.commitDBTransaction();
|
||||||
|
} catch (ApplicationManagementDAOException e) {
|
||||||
|
ConnectionManagerUtil.rollbackDBTransaction();
|
||||||
|
String msg = "Error occurred while updating the status of the subscription.";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new SubscriptionManagementException(msg, e);
|
||||||
|
} catch (TransactionManagementException e) {
|
||||||
|
String msg = "Error occurred while executing database transaction.";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new SubscriptionManagementException(msg, e);
|
||||||
|
} catch (DBConnectionException e) {
|
||||||
|
String msg = "Error occurred while retrieving the database connection";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new SubscriptionManagementException(msg, e);
|
||||||
|
} finally {
|
||||||
|
ConnectionManagerUtil.closeDBConnection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private <T> void validateRequest(List<T> params, String subType, String action) throws BadRequestException {
|
private <T> void validateRequest(List<T> params, String subType, String action) throws BadRequestException {
|
||||||
if (params.isEmpty()) {
|
if (params.isEmpty()) {
|
||||||
String msg = "In order to install application release, you should provide list of subscribers. "
|
String msg = "In order to install application release, you should provide list of subscribers. "
|
||||||
@ -191,7 +313,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
|
|||||||
log.error(msg);
|
log.error(msg);
|
||||||
throw new BadRequestException(msg);
|
throw new BadRequestException(msg);
|
||||||
}
|
}
|
||||||
boolean isValidSubType = Arrays.stream(SubsciptionType.values())
|
boolean isValidSubType = Arrays.stream(SubscriptionType.values())
|
||||||
.anyMatch(sub -> sub.name().equalsIgnoreCase(subType));
|
.anyMatch(sub -> sub.name().equalsIgnoreCase(subType));
|
||||||
if (!isValidSubType) {
|
if (!isValidSubType) {
|
||||||
String msg = "Found invalid subscription type " + subType+ " to install application release" ;
|
String msg = "Found invalid subscription type " + subType+ " to install application release" ;
|
||||||
@ -336,7 +458,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
|
|||||||
ConnectionManagerUtil.beginDBTransaction();
|
ConnectionManagerUtil.beginDBTransaction();
|
||||||
List<Integer> deviceSubIds = new ArrayList<>();
|
List<Integer> deviceSubIds = new ArrayList<>();
|
||||||
|
|
||||||
if (SubsciptionType.USER.toString().equalsIgnoreCase(subType)) {
|
if (SubscriptionType.USER.toString().equalsIgnoreCase(subType)) {
|
||||||
List<String> subscribedEntities = subscriptionDAO.getSubscribedUserNames(params, tenantId);
|
List<String> subscribedEntities = subscriptionDAO.getSubscribedUserNames(params, tenantId);
|
||||||
if (SubAction.INSTALL.toString().equalsIgnoreCase(action)) {
|
if (SubAction.INSTALL.toString().equalsIgnoreCase(action)) {
|
||||||
params.removeAll(subscribedEntities);
|
params.removeAll(subscribedEntities);
|
||||||
@ -344,7 +466,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
|
|||||||
}
|
}
|
||||||
subscriptionDAO.updateSubscriptions(tenantId, username, subscribedEntities, applicationReleaseId, subType,
|
subscriptionDAO.updateSubscriptions(tenantId, username, subscribedEntities, applicationReleaseId, subType,
|
||||||
action);
|
action);
|
||||||
} else if (SubsciptionType.ROLE.toString().equalsIgnoreCase(subType)) {
|
} else if (SubscriptionType.ROLE.toString().equalsIgnoreCase(subType)) {
|
||||||
List<String> subscribedEntities = subscriptionDAO.getSubscribedRoleNames(params, tenantId);
|
List<String> subscribedEntities = subscriptionDAO.getSubscribedRoleNames(params, tenantId);
|
||||||
if (SubAction.INSTALL.toString().equalsIgnoreCase(action)) {
|
if (SubAction.INSTALL.toString().equalsIgnoreCase(action)) {
|
||||||
params.removeAll(subscribedEntities);
|
params.removeAll(subscribedEntities);
|
||||||
@ -352,7 +474,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
|
|||||||
}
|
}
|
||||||
subscriptionDAO.updateSubscriptions(tenantId, username, subscribedEntities, applicationReleaseId, subType,
|
subscriptionDAO.updateSubscriptions(tenantId, username, subscribedEntities, applicationReleaseId, subType,
|
||||||
action);
|
action);
|
||||||
} else if (SubsciptionType.GROUP.toString().equalsIgnoreCase(subType)) {
|
} else if (SubscriptionType.GROUP.toString().equalsIgnoreCase(subType)) {
|
||||||
List<String> subscribedEntities = subscriptionDAO.getSubscribedGroupNames(params, tenantId);
|
List<String> subscribedEntities = subscriptionDAO.getSubscribedGroupNames(params, tenantId);
|
||||||
if (SubAction.INSTALL.toString().equalsIgnoreCase(action)) {
|
if (SubAction.INSTALL.toString().equalsIgnoreCase(action)) {
|
||||||
params.removeAll(subscribedEntities);
|
params.removeAll(subscribedEntities);
|
||||||
|
|||||||
@ -22,20 +22,22 @@ import org.apache.commons.logging.Log;
|
|||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.osgi.framework.BundleContext;
|
import org.osgi.framework.BundleContext;
|
||||||
import org.osgi.service.component.ComponentContext;
|
import org.osgi.service.component.ComponentContext;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.config.LifecycleState;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.config.UIConfiguration;
|
||||||
import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager;
|
import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager;
|
||||||
import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager;
|
import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager;
|
||||||
import org.wso2.carbon.device.application.mgt.common.services.AppmDataHandler;
|
import org.wso2.carbon.device.application.mgt.common.services.AppmDataHandler;
|
||||||
import org.wso2.carbon.device.application.mgt.common.services.ReviewManager;
|
import org.wso2.carbon.device.application.mgt.common.services.ReviewManager;
|
||||||
import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager;
|
import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager;
|
||||||
import org.wso2.carbon.device.application.mgt.core.config.ConfigurationManager;
|
import org.wso2.carbon.device.application.mgt.core.config.ConfigurationManager;
|
||||||
import org.wso2.carbon.device.application.mgt.common.config.UIConfiguration;
|
|
||||||
import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAOFactory;
|
import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAOFactory;
|
||||||
import org.wso2.carbon.device.application.mgt.core.impl.AppmDataHandlerImpl;
|
import org.wso2.carbon.device.application.mgt.core.impl.AppmDataHandlerImpl;
|
||||||
import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager;
|
import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager;
|
||||||
import org.wso2.carbon.device.application.mgt.common.config.LifecycleState;
|
import org.wso2.carbon.device.application.mgt.core.task.ScheduledAppSubscriptionTaskManager;
|
||||||
import org.wso2.carbon.device.application.mgt.core.util.ApplicationManagementUtil;
|
import org.wso2.carbon.device.application.mgt.core.util.ApplicationManagementUtil;
|
||||||
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
|
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
|
||||||
import org.wso2.carbon.ndatasource.core.DataSourceService;
|
import org.wso2.carbon.ndatasource.core.DataSourceService;
|
||||||
|
import org.wso2.carbon.ntask.core.service.TaskService;
|
||||||
import org.wso2.carbon.user.core.service.RealmService;
|
import org.wso2.carbon.user.core.service.RealmService;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -61,7 +63,14 @@ import java.util.List;
|
|||||||
* policy="dynamic"
|
* policy="dynamic"
|
||||||
* bind="setDataSourceService"
|
* bind="setDataSourceService"
|
||||||
* unbind="unsetDataSourceService"
|
* unbind="unsetDataSourceService"
|
||||||
|
* @scr.reference name="app.mgt.ntask.component"
|
||||||
|
* interface="org.wso2.carbon.ntask.core.service.TaskService"
|
||||||
|
* cardinality="1..1"
|
||||||
|
* policy="dynamic"
|
||||||
|
* bind="setTaskService"
|
||||||
|
* unbind="unsetTaskService"
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
public class ApplicationManagementServiceComponent {
|
public class ApplicationManagementServiceComponent {
|
||||||
|
|
||||||
private static Log log = LogFactory.getLog(ApplicationManagementServiceComponent.class);
|
private static Log log = LogFactory.getLog(ApplicationManagementServiceComponent.class);
|
||||||
@ -69,8 +78,6 @@ public class ApplicationManagementServiceComponent {
|
|||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
protected void activate(ComponentContext componentContext) {
|
protected void activate(ComponentContext componentContext) {
|
||||||
|
|
||||||
log.info("CALLING ACTIVATE .............");
|
|
||||||
BundleContext bundleContext = componentContext.getBundleContext();
|
BundleContext bundleContext = componentContext.getBundleContext();
|
||||||
try {
|
try {
|
||||||
String dataSourceName = ConfigurationManager.getInstance().getConfiguration().getDatasourceName();
|
String dataSourceName = ConfigurationManager.getInstance().getConfiguration().getDatasourceName();
|
||||||
@ -108,16 +115,21 @@ public class ApplicationManagementServiceComponent {
|
|||||||
DataHolder.getInstance().setConfigManager(configManager);
|
DataHolder.getInstance().setConfigManager(configManager);
|
||||||
bundleContext.registerService(AppmDataHandler.class.getName(), configManager, null);
|
bundleContext.registerService(AppmDataHandler.class.getName(), configManager, null);
|
||||||
|
|
||||||
|
ScheduledAppSubscriptionTaskManager taskManager = new ScheduledAppSubscriptionTaskManager();
|
||||||
|
taskManager.scheduleCleanupTask();
|
||||||
|
|
||||||
log.info("ApplicationManagement core bundle has been successfully initialized");
|
log.info("ApplicationManagement core bundle has been successfully initialized");
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
log.error("Error occurred while initializing app management core bundle", e);
|
log.error("Error occurred while initializing app management core bundle", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
protected void deactivate(ComponentContext componentContext) {
|
protected void deactivate(ComponentContext componentContext) {
|
||||||
//do nothing
|
//do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
protected void setDeviceManagementService(DeviceManagementProviderService deviceManagementProviderService) {
|
protected void setDeviceManagementService(DeviceManagementProviderService deviceManagementProviderService) {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("Setting ApplicationDTO Management OSGI Manager");
|
log.debug("Setting ApplicationDTO Management OSGI Manager");
|
||||||
@ -125,6 +137,7 @@ public class ApplicationManagementServiceComponent {
|
|||||||
DataHolder.getInstance().setDeviceManagementService(deviceManagementProviderService);
|
DataHolder.getInstance().setDeviceManagementService(deviceManagementProviderService);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
protected void unsetDeviceManagementService(DeviceManagementProviderService deviceManagementProviderService) {
|
protected void unsetDeviceManagementService(DeviceManagementProviderService deviceManagementProviderService) {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("Removing ApplicationDTO Management OSGI Manager");
|
log.debug("Removing ApplicationDTO Management OSGI Manager");
|
||||||
@ -132,21 +145,41 @@ public class ApplicationManagementServiceComponent {
|
|||||||
DataHolder.getInstance().setDeviceManagementService(null);
|
DataHolder.getInstance().setDeviceManagementService(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
protected void setRealmService(RealmService realmService) {
|
protected void setRealmService(RealmService realmService) {
|
||||||
DataHolder.getInstance().setRealmService(realmService);
|
DataHolder.getInstance().setRealmService(realmService);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
protected void unsetRealmService(RealmService realmService) {
|
protected void unsetRealmService(RealmService realmService) {
|
||||||
DataHolder.getInstance().setRealmService(null);
|
DataHolder.getInstance().setRealmService(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
protected void setDataSourceService(DataSourceService dataSourceService) {
|
protected void setDataSourceService(DataSourceService dataSourceService) {
|
||||||
/*Not implemented. Not needed but to make sure the datasource service are registered, as it is needed create
|
/*Not implemented. Not needed but to make sure the datasource service are registered, as it is needed create
|
||||||
databases. */
|
databases. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
protected void unsetDataSourceService(DataSourceService dataSourceService) {
|
protected void unsetDataSourceService(DataSourceService dataSourceService) {
|
||||||
/*Not implemented. Not needed but to make sure the datasource service are registered, as it is needed to create
|
/*Not implemented. Not needed but to make sure the datasource service are registered, as it is needed to create
|
||||||
databases.*/
|
databases.*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public void setTaskService(TaskService taskService) {
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Setting the task service to Application Management SC.");
|
||||||
|
}
|
||||||
|
DataHolder.getInstance().setTaskService(taskService);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
protected void unsetTaskService(TaskService taskService) {
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Removing the task service from Application Management SC");
|
||||||
|
}
|
||||||
|
DataHolder.getInstance().setTaskService(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,6 +25,7 @@ import org.wso2.carbon.device.application.mgt.common.services.ReviewManager;
|
|||||||
import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager;
|
import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager;
|
||||||
import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager;
|
import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager;
|
||||||
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
|
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
|
||||||
|
import org.wso2.carbon.ntask.core.service.TaskService;
|
||||||
import org.wso2.carbon.user.core.service.RealmService;
|
import org.wso2.carbon.user.core.service.RealmService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,6 +49,8 @@ public class DataHolder {
|
|||||||
|
|
||||||
private AppmDataHandler configManager;
|
private AppmDataHandler configManager;
|
||||||
|
|
||||||
|
private TaskService taskService;
|
||||||
|
|
||||||
private static final DataHolder applicationMgtDataHolder = new DataHolder();
|
private static final DataHolder applicationMgtDataHolder = new DataHolder();
|
||||||
|
|
||||||
private DataHolder() {
|
private DataHolder() {
|
||||||
@ -121,4 +124,12 @@ public class DataHolder {
|
|||||||
public void setConfigManager(AppmDataHandler configManager) {
|
public void setConfigManager(AppmDataHandler configManager) {
|
||||||
this.configManager = configManager;
|
this.configManager = configManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TaskService getTaskService() {
|
||||||
|
return taskService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskService(TaskService taskService) {
|
||||||
|
this.taskService = taskService;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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.application.mgt.core.task;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.exception.SubscriptionManagementException;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager;
|
||||||
|
import org.wso2.carbon.device.application.mgt.core.impl.SubscriptionManagerImpl;
|
||||||
|
import org.wso2.carbon.ntask.core.Task;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ScheduledAppSubscriptionCleanupTask implements Task {
|
||||||
|
private static Log log = LogFactory.getLog(ScheduledAppSubscriptionCleanupTask.class);
|
||||||
|
private SubscriptionManager subscriptionManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties(Map<String, String> properties) {
|
||||||
|
//no properties required
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
if (this.subscriptionManager == null) {
|
||||||
|
this.subscriptionManager = new SubscriptionManagerImpl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
try {
|
||||||
|
subscriptionManager.cleanScheduledSubscriptions();
|
||||||
|
} catch (SubscriptionManagementException e) {
|
||||||
|
log.error("Error occurred while cleaning up tasks.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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.application.mgt.core.task;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.ExecutionStatus;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.SubscriptionType;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.dto.ScheduledSubscriptionDTO;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.exception.SubscriptionManagementException;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager;
|
||||||
|
import org.wso2.carbon.device.application.mgt.core.impl.SubscriptionManagerImpl;
|
||||||
|
import org.wso2.carbon.device.application.mgt.core.util.Constants;
|
||||||
|
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
||||||
|
import org.wso2.carbon.ntask.core.Task;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class ScheduledAppSubscriptionTask implements Task {
|
||||||
|
private static Log log = LogFactory.getLog(ScheduledAppSubscriptionTask.class);
|
||||||
|
private SubscriptionManager subscriptionManager;
|
||||||
|
private String subscribers;
|
||||||
|
private String subscriptionType;
|
||||||
|
private String application;
|
||||||
|
private String action;
|
||||||
|
private String subscriber;
|
||||||
|
private String tenantDomain;
|
||||||
|
private String taskName;
|
||||||
|
private int tenantId;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties(Map<String, String> map) {
|
||||||
|
this.subscribers = map.get(Constants.SUBSCRIBERS);
|
||||||
|
this.subscriptionType = map.get(Constants.SUB_TYPE);
|
||||||
|
this.application = map.get(Constants.APP_UUID);
|
||||||
|
this.action = map.get(Constants.ACTION);
|
||||||
|
this.subscriber = map.get(Constants.SUBSCRIBER);
|
||||||
|
this.tenantDomain = map.get(Constants.TENANT_DOMAIN);
|
||||||
|
this.tenantId = Integer.parseInt(map.get(Constants.TENANT_ID));
|
||||||
|
this.taskName = map.get(Constants.TASK_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
if (this.subscriptionManager == null) {
|
||||||
|
this.subscriptionManager = new SubscriptionManagerImpl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
try {
|
||||||
|
ScheduledSubscriptionDTO subscriptionDTO = subscriptionManager.getPendingScheduledSubscription(
|
||||||
|
this.taskName);
|
||||||
|
if (subscriptionDTO == null) {
|
||||||
|
log.error("Unable to execute the task. Task entry for [" + this.taskName + "] cannot be retrieved " +
|
||||||
|
"from the database.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotEmpty(this.subscribers)) {
|
||||||
|
PrivilegedCarbonContext.startTenantFlow();
|
||||||
|
PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
|
||||||
|
carbonContext.setTenantDomain(this.tenantDomain);
|
||||||
|
carbonContext.setTenantId(this.tenantId);
|
||||||
|
carbonContext.setUsername(this.subscriber);
|
||||||
|
|
||||||
|
if (this.subscriptionType.equals(SubscriptionType.DEVICE.toString())) {
|
||||||
|
List<DeviceIdentifier> deviceIdentifiers = new Gson().fromJson(this.subscribers,
|
||||||
|
new TypeToken<List<DeviceIdentifier>>() {
|
||||||
|
}.getType());
|
||||||
|
try {
|
||||||
|
subscriptionManager.performBulkAppOperation(this.application, deviceIdentifiers,
|
||||||
|
this.subscriptionType, this.action);
|
||||||
|
subscriptionDTO.setStatus(ExecutionStatus.EXECUTED);
|
||||||
|
} catch (ApplicationManagementException e) {
|
||||||
|
log.error(
|
||||||
|
"Error occurred while " + this.action + "ing application " + this.application
|
||||||
|
+ "to/from the following devices: " + this.subscribers, e);
|
||||||
|
subscriptionDTO.setStatus(ExecutionStatus.FAILED);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
List<String> subscriberList = Pattern.compile(",").splitAsStream(this.subscribers).collect(
|
||||||
|
Collectors.toList());
|
||||||
|
try {
|
||||||
|
subscriptionManager.performBulkAppOperation(this.application, subscriberList,
|
||||||
|
this.subscriptionType, this.action);
|
||||||
|
subscriptionDTO.setStatus(ExecutionStatus.EXECUTED);
|
||||||
|
} catch (ApplicationManagementException e) {
|
||||||
|
log.error(
|
||||||
|
"Error occurred while " + this.action + "ing application " + this.application
|
||||||
|
+ "to/from the following " + this.subscriptionType + "s: " + this.subscribers, e);
|
||||||
|
subscriptionDTO.setStatus(ExecutionStatus.FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn(
|
||||||
|
"Subscriber list is empty. Therefore skipping scheduled task to " + this.action + "application "
|
||||||
|
+ this.application);
|
||||||
|
subscriptionDTO.setStatus(ExecutionStatus.FAILED);
|
||||||
|
}
|
||||||
|
subscriptionManager.updateScheduledSubscriptionStatus(subscriptionDTO.getId(), subscriptionDTO.getStatus());
|
||||||
|
} catch (SubscriptionManagementException e) {
|
||||||
|
log.error("Error occurred while executing the task: " + this.taskName, e);
|
||||||
|
} finally {
|
||||||
|
PrivilegedCarbonContext.endTenantFlow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,220 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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.application.mgt.core.task;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.quartz.CronExpression;
|
||||||
|
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.SubAction;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.SubscriptionType;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.dto.ScheduledSubscriptionDTO;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.exception.SubscriptionManagementException;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager;
|
||||||
|
import org.wso2.carbon.device.application.mgt.core.exception.ApplicationOperationTaskException;
|
||||||
|
import org.wso2.carbon.device.application.mgt.core.impl.SubscriptionManagerImpl;
|
||||||
|
import org.wso2.carbon.device.application.mgt.core.internal.DataHolder;
|
||||||
|
import org.wso2.carbon.device.application.mgt.core.util.Constants;
|
||||||
|
import org.wso2.carbon.ntask.common.TaskException;
|
||||||
|
import org.wso2.carbon.ntask.core.TaskInfo;
|
||||||
|
import org.wso2.carbon.ntask.core.TaskManager;
|
||||||
|
import org.wso2.carbon.ntask.core.service.TaskService;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.TextStyle;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class ScheduledAppSubscriptionTaskManager {
|
||||||
|
private static Log log = LogFactory.getLog(ScheduledAppSubscriptionTaskManager.class);
|
||||||
|
private static final String SCHEDULED_APP_SUBSCRIPTION_TASK_TYPE = "SCHEDULED_APP_SUBSCRIPTION_TASK_TYPE";
|
||||||
|
private static final String NAME_SEPARATOR = "_";
|
||||||
|
private SubscriptionManager subscriptionManager;
|
||||||
|
|
||||||
|
public ScheduledAppSubscriptionTaskManager() {
|
||||||
|
this.subscriptionManager = new SubscriptionManagerImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedule a task to install/uninstall application for a list of subscribers
|
||||||
|
*
|
||||||
|
* @param applicationUUID UUID of the application to install
|
||||||
|
* @param subscribers list of subscribers. This list can be of
|
||||||
|
* either {@link org.wso2.carbon.device.mgt.common.DeviceIdentifier} if {@param subType} is
|
||||||
|
* equal to DEVICE or {@link String} if {@param subType} is USER, ROLE or GROUP
|
||||||
|
* @param subscriptionType subscription type. E.g. <code>DEVICE, USER, ROLE, GROUP</code>
|
||||||
|
* {@see {@link org.wso2.carbon.device.application.mgt.common.SubscriptionType}}
|
||||||
|
* @param action action subscription action. E.g. {@code INSTALL/UNINSTALL}
|
||||||
|
* {@see {@link org.wso2.carbon.device.application.mgt.common.SubAction}}
|
||||||
|
* @param timestamp timestamp to schedule the application subscription
|
||||||
|
* @throws ApplicationOperationTaskException if error occurred while scheduling the subscription
|
||||||
|
*/
|
||||||
|
public void scheduleAppSubscriptionTask(String applicationUUID, List<?> subscribers,
|
||||||
|
SubscriptionType subscriptionType, SubAction action, LocalDateTime timestamp)
|
||||||
|
throws ApplicationOperationTaskException {
|
||||||
|
String space = " ";
|
||||||
|
String cronExpression =
|
||||||
|
String.valueOf(timestamp.getSecond()) + space + timestamp.getMinute() + space + timestamp.getHour()
|
||||||
|
+ space + timestamp.getDayOfMonth() + space + timestamp.getMonth().getDisplayName(TextStyle.SHORT,
|
||||||
|
Locale.getDefault()).toUpperCase() + " ? " + timestamp.getYear();
|
||||||
|
|
||||||
|
if (!CronExpression.isValidExpression(cronExpression)) {
|
||||||
|
String msg = "The cron expression [" + cronExpression + "] generated by the" + " timestamp [" + timestamp
|
||||||
|
.toString() + "] is invalid";
|
||||||
|
log.error(msg);
|
||||||
|
throw new ApplicationOperationTaskException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
|
||||||
|
TaskService taskService = initializeTaskType();
|
||||||
|
|
||||||
|
TaskManager taskManager = taskService.getTaskManager(SCHEDULED_APP_SUBSCRIPTION_TASK_TYPE);
|
||||||
|
TaskInfo.TriggerInfo triggerInfo = new TaskInfo.TriggerInfo();
|
||||||
|
triggerInfo.setCronExpression(cronExpression);
|
||||||
|
triggerInfo.setRepeatCount(0);
|
||||||
|
|
||||||
|
Map<String, String> taskProperties = new HashMap<>();
|
||||||
|
taskProperties.put(Constants.SUB_TYPE, subscriptionType.toString());
|
||||||
|
taskProperties.put(Constants.ACTION, action.toString());
|
||||||
|
taskProperties.put(Constants.APP_UUID, applicationUUID);
|
||||||
|
taskProperties.put(Constants.TENANT_DOMAIN, carbonContext.getTenantDomain(true));
|
||||||
|
taskProperties.put(Constants.SUBSCRIBER, carbonContext.getUsername());
|
||||||
|
|
||||||
|
String subscribersString;
|
||||||
|
if (SubscriptionType.DEVICE.equals(subscriptionType)) {
|
||||||
|
subscribersString = new Gson().toJson(subscribers);
|
||||||
|
taskProperties.put(Constants.SUBSCRIBERS, subscribersString);
|
||||||
|
} else {
|
||||||
|
subscribersString = subscribers.stream().map(String.class::cast).collect(Collectors.joining(","));
|
||||||
|
taskProperties.put(Constants.SUBSCRIBERS, subscribersString);
|
||||||
|
}
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Scheduling a task to " + action.toString() + " application: " + applicationUUID +
|
||||||
|
" to/from the following " + subscriptionType.toString() + "S [" + subscribersString + "] at: "
|
||||||
|
+ timestamp);
|
||||||
|
}
|
||||||
|
String taskName = subscriptionType.toString() + NAME_SEPARATOR + action.toString() + NAME_SEPARATOR
|
||||||
|
+ DigestUtils.md5Hex(applicationUUID + NAME_SEPARATOR + subscribersString);
|
||||||
|
taskProperties.put(Constants.TASK_NAME, taskName);
|
||||||
|
TaskInfo taskInfo = new TaskInfo(taskName, ScheduledAppSubscriptionTask.class.getName(),
|
||||||
|
taskProperties, triggerInfo);
|
||||||
|
|
||||||
|
ScheduledSubscriptionDTO subscriptionDTO = new ScheduledSubscriptionDTO(taskName, applicationUUID,
|
||||||
|
timestamp, subscribers, carbonContext.getUsername());
|
||||||
|
subscriptionManager.createScheduledSubscription(subscriptionDTO);
|
||||||
|
|
||||||
|
taskManager.registerTask(taskInfo);
|
||||||
|
if (!taskManager.isTaskScheduled(taskName)) {
|
||||||
|
taskManager.scheduleTask(taskName);
|
||||||
|
} else {
|
||||||
|
taskManager.rescheduleTask(taskName);
|
||||||
|
}
|
||||||
|
} catch (TaskException e) {
|
||||||
|
String msg = "Error occurred while scheduling a task to " + action.toString() + " application: "
|
||||||
|
+ applicationUUID + " to/from given " + subscriptionType.toString() + "S";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new ApplicationOperationTaskException(msg, e);
|
||||||
|
} catch (SubscriptionManagementException e) {
|
||||||
|
String msg = "Error occurred while writing the subscription to database";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new ApplicationOperationTaskException(msg, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules a task to clean up the scheduled tasks from {@link org.wso2.carbon.ntask.core.TaskRepository}
|
||||||
|
*/
|
||||||
|
public void scheduleCleanupTask() {
|
||||||
|
try {
|
||||||
|
TaskService taskService = initializeTaskType();
|
||||||
|
TaskManager taskManager = taskService.getTaskManager(SCHEDULED_APP_SUBSCRIPTION_TASK_TYPE);
|
||||||
|
|
||||||
|
TaskInfo.TriggerInfo triggerInfo = new TaskInfo.TriggerInfo();
|
||||||
|
triggerInfo.setCronExpression("0 0 0/24 ? * * *");
|
||||||
|
|
||||||
|
String taskName = "SCHEDULED_APP_SUBSCRIPTION_CLEANUP_TASK";
|
||||||
|
TaskInfo taskInfo = new TaskInfo(taskName, ScheduledAppSubscriptionCleanupTask.class.getName(), null,
|
||||||
|
triggerInfo);
|
||||||
|
|
||||||
|
taskManager.registerTask(taskInfo);
|
||||||
|
if (!taskManager.isTaskScheduled(taskName)) {
|
||||||
|
taskManager.scheduleTask(taskName);
|
||||||
|
} else {
|
||||||
|
taskManager.rescheduleTask(taskName);
|
||||||
|
}
|
||||||
|
} catch (TaskException e) {
|
||||||
|
log.error("Error occurred while scheduling a cleanup task.");
|
||||||
|
} catch (ApplicationOperationTaskException e) {
|
||||||
|
log.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize task type.
|
||||||
|
*
|
||||||
|
* @return {@link TaskService}
|
||||||
|
* @throws TaskException if error occurred while initializing task type
|
||||||
|
* @throws ApplicationOperationTaskException if unable to load {@link TaskService}
|
||||||
|
*/
|
||||||
|
private TaskService initializeTaskType() throws TaskException, ApplicationOperationTaskException {
|
||||||
|
TaskService taskService = DataHolder.getInstance().getTaskService();
|
||||||
|
if (taskService == null) {
|
||||||
|
String msg = "Unable to load TaskService, hence unable to schedule the task.";
|
||||||
|
log.error(msg);
|
||||||
|
throw new ApplicationOperationTaskException(msg);
|
||||||
|
}
|
||||||
|
if (!taskService.getRegisteredTaskTypes().contains(SCHEDULED_APP_SUBSCRIPTION_TASK_TYPE)) {
|
||||||
|
try {
|
||||||
|
List<ScheduledSubscriptionDTO> removedTaskList = subscriptionManager.cleanScheduledSubscriptions();
|
||||||
|
removeScheduledSubscriptions(taskService, removedTaskList);
|
||||||
|
} catch (SubscriptionManagementException e) {
|
||||||
|
log.error("Error occurred while retrieving tasks to cleanup", e);
|
||||||
|
}
|
||||||
|
taskService.registerTaskType(SCHEDULED_APP_SUBSCRIPTION_TASK_TYPE);
|
||||||
|
}
|
||||||
|
return taskService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleans up already scheduled subscriptions.
|
||||||
|
*
|
||||||
|
* @param taskList list of {@link ScheduledSubscriptionDTO}s to remove
|
||||||
|
*/
|
||||||
|
private void removeScheduledSubscriptions(TaskService taskService, List<ScheduledSubscriptionDTO> taskList) {
|
||||||
|
try {
|
||||||
|
TaskManager taskManager = taskService.getTaskManager(SCHEDULED_APP_SUBSCRIPTION_TASK_TYPE);
|
||||||
|
taskManager.getAllTasks().forEach(
|
||||||
|
task -> taskList.stream().filter(t -> t.getTaskName().equals(task.getName())).forEach(t -> {
|
||||||
|
try {
|
||||||
|
taskManager.deleteTask(t.getTaskName());
|
||||||
|
} catch (TaskException e) {
|
||||||
|
log.error("Error occurred while removing the task: " + t.getTaskName(), e);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
} catch (TaskException e) {
|
||||||
|
log.error("Error occurred while removing tasks", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -16,6 +16,25 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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.application.mgt.core.util;
|
package org.wso2.carbon.device.application.mgt.core.util;
|
||||||
|
|
||||||
import org.wso2.carbon.utils.CarbonUtils;
|
import org.wso2.carbon.utils.CarbonUtils;
|
||||||
@ -49,6 +68,16 @@ public class Constants {
|
|||||||
public static final String GOOGLE_PLAY_STORE_URL = "https://play.google.com/store/apps/details?id=";
|
public static final String GOOGLE_PLAY_STORE_URL = "https://play.google.com/store/apps/details?id=";
|
||||||
public static final String APPLE_STORE_URL = "https://itunes.apple.com/country/app/app-name/id";
|
public static final String APPLE_STORE_URL = "https://itunes.apple.com/country/app/app-name/id";
|
||||||
|
|
||||||
|
// Subscription task related constants
|
||||||
|
public static final String SUBSCRIBERS = "SUBSCRIBERS";
|
||||||
|
public static final String SUB_TYPE = "SUBSCRIPTION_TYPE";
|
||||||
|
public static final String ACTION = "ACTION";
|
||||||
|
public static final String APP_UUID = "APP_UUID";
|
||||||
|
public static final String SUBSCRIBER = "SUBSCRIBER";
|
||||||
|
public static final String TENANT_DOMAIN = "TENANT_DOMAIN";
|
||||||
|
public static final String TENANT_ID = "__TENANT_ID_PROP__";
|
||||||
|
public static final String TASK_NAME = "TASK_NAME";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Database types supported by Application Management.
|
* Database types supported by Application Management.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -16,21 +16,45 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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.application.mgt.core.util;
|
package org.wso2.carbon.device.application.mgt.core.util;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.ExecutionStatus;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.SubscriptionType;
|
||||||
import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO;
|
import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO;
|
||||||
|
|
||||||
import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO;
|
import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO;
|
||||||
import org.wso2.carbon.device.application.mgt.common.dto.DeviceSubscriptionDTO;
|
import org.wso2.carbon.device.application.mgt.common.dto.DeviceSubscriptionDTO;
|
||||||
import org.wso2.carbon.device.application.mgt.common.dto.ReviewDTO;
|
import org.wso2.carbon.device.application.mgt.common.dto.ReviewDTO;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.dto.ScheduledSubscriptionDTO;
|
||||||
import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager;
|
import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager;
|
||||||
import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager;
|
import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager;
|
||||||
import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager;
|
import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager;
|
||||||
import org.wso2.carbon.device.application.mgt.core.exception.UnexpectedServerErrorException;
|
import org.wso2.carbon.device.application.mgt.core.exception.UnexpectedServerErrorException;
|
||||||
|
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
||||||
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
|
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
|
||||||
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl;
|
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl;
|
||||||
|
|
||||||
@ -39,6 +63,8 @@ import java.sql.ResultSet;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is responsible for handling the utils of the Application Management DAO.
|
* This class is responsible for handling the utils of the Application Management DAO.
|
||||||
@ -237,6 +263,49 @@ public class DAOUtil {
|
|||||||
return reviewDTOs;
|
return reviewDTOs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ScheduledSubscriptionDTO loadScheduledSubscription(ResultSet rs)
|
||||||
|
throws SQLException, UnexpectedServerErrorException {
|
||||||
|
List<ScheduledSubscriptionDTO> subscriptionDTOs = loadScheduledSubscriptions(rs);
|
||||||
|
|
||||||
|
if (subscriptionDTOs.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (subscriptionDTOs.size() > 1) {
|
||||||
|
String msg = "Internal server error. Found more than one subscription for requested pending subscription";
|
||||||
|
log.error(msg);
|
||||||
|
throw new UnexpectedServerErrorException(msg);
|
||||||
|
}
|
||||||
|
return subscriptionDTOs.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<ScheduledSubscriptionDTO> loadScheduledSubscriptions(ResultSet rs) throws SQLException {
|
||||||
|
List<ScheduledSubscriptionDTO> subscriptionDTOS = new ArrayList<>();
|
||||||
|
while (rs.next()) {
|
||||||
|
ScheduledSubscriptionDTO subscription = new ScheduledSubscriptionDTO();
|
||||||
|
subscription.setId(rs.getInt("ID"));
|
||||||
|
subscription.setTaskName(rs.getString("TASK_NAME"));
|
||||||
|
subscription.setApplicationUUID(rs.getString("APPLICATION_UUID"));
|
||||||
|
|
||||||
|
if (subscription.getTaskName().startsWith(SubscriptionType.DEVICE.toString())) {
|
||||||
|
List<DeviceIdentifier> deviceIdentifiers = new Gson().fromJson(rs.getString("SUBSCRIBER_LIST"),
|
||||||
|
new TypeToken<List<DeviceIdentifier>>() {
|
||||||
|
}.getType());
|
||||||
|
subscription.setSubscriberList(deviceIdentifiers);
|
||||||
|
} else {
|
||||||
|
List<String> subscriberList = Pattern.compile(",").splitAsStream(rs.getString("SUBSCRIBER_LIST"))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
subscription.setSubscriberList(subscriberList);
|
||||||
|
}
|
||||||
|
|
||||||
|
subscription.setStatus(ExecutionStatus.valueOf(rs.getString("STATUS")));
|
||||||
|
subscription.setScheduledAt(rs.getTimestamp("SCHEDULED_AT").toLocalDateTime());
|
||||||
|
subscription.setScheduledBy(rs.getString("SCHEDULED_BY"));
|
||||||
|
subscription.setDeleted(rs.getBoolean("DELETED"));
|
||||||
|
subscriptionDTOS.add(subscription);
|
||||||
|
}
|
||||||
|
return subscriptionDTOS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cleans up the statement and resultset after executing the query
|
* Cleans up the statement and resultset after executing the query
|
||||||
*
|
*
|
||||||
|
|||||||
@ -35,6 +35,7 @@ import javax.ws.rs.POST;
|
|||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -120,7 +121,12 @@ public interface SubscriptionManagementAPI {
|
|||||||
value = "The application ID and list of devices/users/roles",
|
value = "The application ID and list of devices/users/roles",
|
||||||
required = true
|
required = true
|
||||||
)
|
)
|
||||||
@Valid List<DeviceIdentifier> deviceIdentifiers
|
@Valid List<DeviceIdentifier> deviceIdentifiers,
|
||||||
|
@ApiParam(
|
||||||
|
name = "timestamp",
|
||||||
|
value = "Timestamp of scheduled install/uninstall operation"
|
||||||
|
)
|
||||||
|
@QueryParam("timestamp") String timestamp
|
||||||
);
|
);
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@ -168,6 +174,11 @@ public interface SubscriptionManagementAPI {
|
|||||||
value = "Subscriber list of the application release.",
|
value = "Subscriber list of the application release.",
|
||||||
required = true
|
required = true
|
||||||
)
|
)
|
||||||
@Valid List<String> subscribers
|
@Valid List<String> subscribers,
|
||||||
|
@ApiParam(
|
||||||
|
name = "timestamp",
|
||||||
|
value = "Timestamp of scheduled install/uninstall operation"
|
||||||
|
)
|
||||||
|
@QueryParam("timestamp") String timestamp
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,19 +15,43 @@
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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.application.mgt.store.api.services.impl;
|
package org.wso2.carbon.device.application.mgt.store.api.services.impl;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponse;
|
import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponse;
|
||||||
import org.wso2.carbon.device.application.mgt.common.SubsciptionType;
|
import org.wso2.carbon.device.application.mgt.common.ErrorResponse;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.SubAction;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.SubscriptionType;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
|
||||||
|
import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager;
|
||||||
|
import org.wso2.carbon.device.application.mgt.core.exception.ApplicationOperationTaskException;
|
||||||
import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException;
|
import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException;
|
||||||
import org.wso2.carbon.device.application.mgt.core.exception.ForbiddenException;
|
import org.wso2.carbon.device.application.mgt.core.exception.ForbiddenException;
|
||||||
import org.wso2.carbon.device.application.mgt.core.exception.NotFoundException;
|
import org.wso2.carbon.device.application.mgt.core.exception.NotFoundException;
|
||||||
import org.wso2.carbon.device.application.mgt.store.api.services.SubscriptionManagementAPI;
|
import org.wso2.carbon.device.application.mgt.core.task.ScheduledAppSubscriptionTaskManager;
|
||||||
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
|
|
||||||
import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager;
|
|
||||||
import org.wso2.carbon.device.application.mgt.core.util.APIUtil;
|
import org.wso2.carbon.device.application.mgt.core.util.APIUtil;
|
||||||
|
import org.wso2.carbon.device.application.mgt.store.api.services.SubscriptionManagementAPI;
|
||||||
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
@ -35,7 +59,10 @@ import javax.ws.rs.POST;
|
|||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,30 +80,36 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
|
|||||||
public Response performAppOperationForDevices(
|
public Response performAppOperationForDevices(
|
||||||
@PathParam("uuid") String uuid,
|
@PathParam("uuid") String uuid,
|
||||||
@PathParam("action") String action,
|
@PathParam("action") String action,
|
||||||
@Valid List<DeviceIdentifier> deviceIdentifiers) {
|
@Valid List<DeviceIdentifier> deviceIdentifiers,
|
||||||
|
@QueryParam("timestamp") String timestamp) {
|
||||||
try {
|
try {
|
||||||
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
|
if (StringUtils.isEmpty(timestamp)) {
|
||||||
ApplicationInstallResponse response = subscriptionManager
|
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
|
||||||
.performBulkAppOperation(uuid, deviceIdentifiers, SubsciptionType.DEVICE.toString(), action);
|
ApplicationInstallResponse response = subscriptionManager
|
||||||
return Response.status(Response.Status.OK).entity(response).build();
|
.performBulkAppOperation(uuid, deviceIdentifiers, SubscriptionType.DEVICE.toString(), action);
|
||||||
|
return Response.status(Response.Status.OK).entity(response).build();
|
||||||
|
} else {
|
||||||
|
return scheduleApplicationOperationTask(uuid, deviceIdentifiers, SubscriptionType.DEVICE,
|
||||||
|
SubAction.valueOf(action.toUpperCase()), timestamp);
|
||||||
|
}
|
||||||
} catch (NotFoundException e) {
|
} catch (NotFoundException e) {
|
||||||
String msg = "Couldn't found an application release for UUI: " + uuid;
|
String msg = "Couldn't found an application release for UUI: " + uuid;
|
||||||
log.error(msg);
|
log.error(msg, e);
|
||||||
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
|
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
|
||||||
} catch (BadRequestException e) {
|
} catch (BadRequestException e) {
|
||||||
String msg = "Found invalid payload for installing application which has UUID: " + uuid
|
String msg = "Found invalid payload for installing application which has UUID: " + uuid
|
||||||
+ ". Hence verify the payload";
|
+ ". Hence verify the payload";
|
||||||
log.error(msg);
|
log.error(msg, e);
|
||||||
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
|
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
|
||||||
} catch (ForbiddenException e) {
|
} catch (ForbiddenException e) {
|
||||||
String msg = "Application release is not in the installable state. Hence you are not permitted to install "
|
String msg = "Application release is not in the installable state. Hence you are not permitted to install "
|
||||||
+ "the application.";
|
+ "the application.";
|
||||||
log.error(msg);
|
log.error(msg, e);
|
||||||
return Response.status(Response.Status.FORBIDDEN).entity(msg).build();
|
return Response.status(Response.Status.FORBIDDEN).entity(msg).build();
|
||||||
} catch (ApplicationManagementException e) {
|
} catch (ApplicationManagementException e) {
|
||||||
String msg =
|
String msg =
|
||||||
"Error occurred while installing the application release which has UUID: " + uuid + " for devices";
|
"Error occurred while installing the application release which has UUID: " + uuid + " for devices";
|
||||||
log.error(msg);
|
log.error(msg, e);
|
||||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,31 +121,68 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
|
|||||||
@PathParam("uuid") String uuid,
|
@PathParam("uuid") String uuid,
|
||||||
@PathParam("subType") String subType,
|
@PathParam("subType") String subType,
|
||||||
@PathParam("action") String action,
|
@PathParam("action") String action,
|
||||||
@Valid List<String> subscribers) {
|
@Valid List<String> subscribers,
|
||||||
|
@QueryParam("timestamp") String timestamp) {
|
||||||
try {
|
try {
|
||||||
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
|
if (StringUtils.isEmpty(timestamp)) {
|
||||||
ApplicationInstallResponse response = subscriptionManager
|
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
|
||||||
.performBulkAppOperation(uuid, subscribers, subType, action);
|
ApplicationInstallResponse response = subscriptionManager
|
||||||
return Response.status(Response.Status.OK).entity(response).build();
|
.performBulkAppOperation(uuid, subscribers, subType, action);
|
||||||
|
return Response.status(Response.Status.OK).entity(response).build();
|
||||||
|
} else {
|
||||||
|
return scheduleApplicationOperationTask(uuid, subscribers,
|
||||||
|
SubscriptionType.valueOf(subType.toUpperCase()), SubAction.valueOf(action.toUpperCase()),
|
||||||
|
timestamp);
|
||||||
|
}
|
||||||
} catch (NotFoundException e) {
|
} catch (NotFoundException e) {
|
||||||
String msg = "Couldn't found an application release for UUID: " + uuid + ". Hence, verify the payload";
|
String msg = "Couldn't found an application release for UUID: " + uuid + ". Hence, verify the payload";
|
||||||
log.error(msg);
|
log.error(msg, e);
|
||||||
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
|
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
|
||||||
} catch (BadRequestException e) {
|
} catch (BadRequestException e) {
|
||||||
String msg = "Found invalid payload for installing application which has UUID: " + uuid
|
String msg = "Found invalid payload for installing application which has UUID: " + uuid
|
||||||
+ ". Hence verify the payload";
|
+ ". Hence verify the payload";
|
||||||
log.error(msg);
|
log.error(msg, e);
|
||||||
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
|
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
|
||||||
} catch (ForbiddenException e) {
|
} catch (ForbiddenException e) {
|
||||||
String msg = "Application release is not in the installable state. Hence you are not permitted to install "
|
String msg = "Application release is not in the installable state. Hence you are not permitted to install "
|
||||||
+ "the application.";
|
+ "the application.";
|
||||||
log.error(msg);
|
log.error(msg, e);
|
||||||
return Response.status(Response.Status.FORBIDDEN).entity(msg).build();
|
return Response.status(Response.Status.FORBIDDEN).entity(msg).build();
|
||||||
} catch (ApplicationManagementException e) {
|
} catch (ApplicationManagementException e) {
|
||||||
String msg = "Error occurred while installing the application release which has UUID: " + uuid
|
String msg = "Error occurred while installing the application release which has UUID: " + uuid
|
||||||
+ " for user devices";
|
+ " for user devices";
|
||||||
log.error(msg);
|
log.error(msg, e);
|
||||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedule the application subscription for the given timestamp
|
||||||
|
*
|
||||||
|
* @param applicationUUID UUID of the application to install
|
||||||
|
* @param subscribers list of subscribers. This list can be of
|
||||||
|
* either {@link org.wso2.carbon.device.mgt.common.DeviceIdentifier} if {@param subType} is
|
||||||
|
* equal to DEVICE or {@link String} if {@param subType} is USER, ROLE or GROUP
|
||||||
|
* @param subType subscription type. E.g. <code>DEVICE, USER, ROLE, GROUP</code>
|
||||||
|
* {@see {@link org.wso2.carbon.device.application.mgt.common.SubscriptionType}}
|
||||||
|
* @param subAction action subscription action. E.g. <code>INSTALL/UNINSTALL</code>
|
||||||
|
* {@see {@link org.wso2.carbon.device.application.mgt.common.SubAction}}
|
||||||
|
* @param timestamp timestamp to schedule the application subscription
|
||||||
|
* @return {@link Response} of the operation
|
||||||
|
*/
|
||||||
|
private Response scheduleApplicationOperationTask(String applicationUUID, List<?> subscribers,
|
||||||
|
SubscriptionType subType, SubAction subAction, String timestamp) {
|
||||||
|
try {
|
||||||
|
ScheduledAppSubscriptionTaskManager subscriptionTaskManager = new ScheduledAppSubscriptionTaskManager();
|
||||||
|
subscriptionTaskManager.scheduleAppSubscriptionTask(applicationUUID, subscribers, subType, subAction,
|
||||||
|
LocalDateTime.parse(timestamp, DateTimeFormatter.ISO_LOCAL_DATE_TIME));
|
||||||
|
} catch (ApplicationOperationTaskException e) {
|
||||||
|
String msg = "Error occurred while scheduling the application install operation";
|
||||||
|
log.error(msg, e);
|
||||||
|
ErrorResponse errorResponse = new ErrorResponse(msg);
|
||||||
|
errorResponse.setDescription(e.getMessage());
|
||||||
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorResponse).build();
|
||||||
|
}
|
||||||
|
return Response.status(Response.Status.CREATED).build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,31 +17,31 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<datasources-configuration xmlns:svns="http://org.wso2.securevault/configuration">
|
<datasources-configuration xmlns:svns="http://org.wso2.securevault/configuration">
|
||||||
<providers>
|
<providers>
|
||||||
<provider>org.wso2.carbon.ndatasource.rdbms.RDBMSDataSourceReader</provider>
|
<provider>org.wso2.carbon.ndatasource.rdbms.RDBMSDataSourceReader</provider>
|
||||||
</providers>
|
</providers>
|
||||||
|
|
||||||
<datasources>
|
<datasources>
|
||||||
<datasource>
|
<datasource>
|
||||||
<name>APPM_DS</name>
|
<name>APPM_DS</name>
|
||||||
<description>The datasource used for CDM Application Management</description>
|
<description>The datasource used for CDM Application Management</description>
|
||||||
<jndiConfig>
|
<jndiConfig>
|
||||||
<name>jdbc/APPM_DS</name>
|
<name>jdbc/APPM_DS</name>
|
||||||
</jndiConfig>
|
</jndiConfig>
|
||||||
<definition type="RDBMS">
|
<definition type="RDBMS">
|
||||||
<configuration>
|
<configuration>
|
||||||
<url>jdbc:h2:repository/database/WSO2DM_APPM_DB;DB_CLOSE_ON_EXIT=FALSE</url>
|
<url>jdbc:h2:repository/database/WSO2DM_APPM_DB;DB_CLOSE_ON_EXIT=FALSE</url>
|
||||||
<username>wso2carbon</username>
|
<username>wso2carbon</username>
|
||||||
<password>wso2carbon</password>
|
<password>wso2carbon</password>
|
||||||
<driverClassName>org.h2.Driver</driverClassName>
|
<driverClassName>org.h2.Driver</driverClassName>
|
||||||
<maxActive>50</maxActive>
|
<maxActive>50</maxActive>
|
||||||
<maxWait>60000</maxWait>
|
<maxWait>60000</maxWait>
|
||||||
<testOnBorrow>true</testOnBorrow>
|
<testOnBorrow>true</testOnBorrow>
|
||||||
<validationQuery>SELECT 1</validationQuery>
|
<validationQuery>SELECT 1</validationQuery>
|
||||||
<validationInterval>30000</validationInterval>
|
<validationInterval>30000</validationInterval>
|
||||||
</configuration>
|
</configuration>
|
||||||
</definition>
|
</definition>
|
||||||
</datasource>
|
</datasource>
|
||||||
</datasources>
|
</datasources>
|
||||||
</datasources-configuration>
|
</datasources-configuration>
|
||||||
|
|
||||||
|
|||||||
@ -256,3 +256,22 @@ CREATE TABLE IF NOT EXISTS AP_APP_SUB_OP_MAPPING (
|
|||||||
REFERENCES AP_DEVICE_SUBSCRIPTION (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
|
REFERENCES AP_DEVICE_SUBSCRIPTION (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
|
||||||
);
|
);
|
||||||
CREATE INDEX fk_AP_APP_SUB_OP_MAPPING_AP_DEVICE_SUBSCRIPTION1_idx ON AP_APP_SUB_OP_MAPPING (AP_DEVICE_SUBSCRIPTION_ID ASC);
|
CREATE INDEX fk_AP_APP_SUB_OP_MAPPING_AP_DEVICE_SUBSCRIPTION1_idx ON AP_APP_SUB_OP_MAPPING (AP_DEVICE_SUBSCRIPTION_ID ASC);
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Table AP_SCHEDULED_SUBSCRIPTION
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS AP_SCHEDULED_SUBSCRIPTION(
|
||||||
|
ID INTEGER NOT NULL AUTO_INCREMENT,
|
||||||
|
TASK_NAME VARCHAR(100) NOT NULL,
|
||||||
|
APPLICATION_UUID VARCHAR(36) NOT NULL,
|
||||||
|
SUBSCRIBER_LIST LONGVARCHAR NOT NULL,
|
||||||
|
STATUS VARCHAR(15) NOT NULL,
|
||||||
|
SCHEDULED_AT TIMESTAMP NOT NULL,
|
||||||
|
SCHEDULED_BY VARCHAR(100) NOT NULL,
|
||||||
|
SCHEDULED_TIMESTAMP TIMESTAMP NOT NULL,
|
||||||
|
DELETED BOOLEAN,
|
||||||
|
PRIMARY KEY (ID),
|
||||||
|
CONSTRAINT fk_AP_SCHEDULED_SUBSCRIPTION_AP_APP_RELEASE
|
||||||
|
FOREIGN KEY (APPLICATION_UUID)
|
||||||
|
REFERENCES AP_APP_RELEASE (UUID) ON DELETE NO ACTION ON UPDATE NO ACTION
|
||||||
|
);
|
||||||
|
|||||||
@ -40,4 +40,19 @@ FOREIGN KEY(PLATFORM_ID) REFERENCES APPM_PLATFORM(ID) ON DELETE CASCADE,
|
|||||||
PRIMARY KEY (PLATFORM_ID, NAME)
|
PRIMARY KEY (PLATFORM_ID, NAME)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[AP_SCHEDULED_SUBSCRIPTION]') AND TYPE IN (N'U'))
|
||||||
|
CREATE TABLE AP_SCHEDULED_SUBSCRIPTION(
|
||||||
|
ID INT IDENTITY(1, 1) NOT NULL,
|
||||||
|
TASK_NAME VARCHAR(100) NOT NULL,
|
||||||
|
APPLICATION_UUID VARCHAR(36) NOT NULL,
|
||||||
|
SUBSCRIBER_LIST VARCHAR(MAX) NOT NULL,
|
||||||
|
STATUS VARCHAR(15) NOT NULL,
|
||||||
|
SCHEDULED_AT DATETIME NOT NULL,
|
||||||
|
SCHEDULED_BY VARCHAR(100) NOT NULL,
|
||||||
|
SCHEDULED_TIMESTAMP DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
DELETED BIT NULL,
|
||||||
|
PRIMARY KEY (ID),
|
||||||
|
FOREIGN KEY (APPLICATION_UUID) REFERENCES AP_APP_RELEASE (UUID) ON DELETE NO ACTION ON UPDATE NO ACTION
|
||||||
|
)
|
||||||
|
|
||||||
CREATE INDEX FK_PLATFROM_TENANT_MAPPING_PLATFORM ON APPM_PLATFORM_TENANT_MAPPING(PLATFORM_ID ASC);
|
CREATE INDEX FK_PLATFROM_TENANT_MAPPING_PLATFORM ON APPM_PLATFORM_TENANT_MAPPING(PLATFORM_ID ASC);
|
||||||
@ -331,3 +331,24 @@ CREATE TABLE IF NOT EXISTS `APP_MANAGER`.`AP_APP_OP_DEVICE_MAPPING` (
|
|||||||
ON UPDATE NO ACTION)
|
ON UPDATE NO ACTION)
|
||||||
ENGINE = InnoDB
|
ENGINE = InnoDB
|
||||||
DEFAULT CHARACTER SET = utf8;
|
DEFAULT CHARACTER SET = utf8;
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Table `APP_MANAGER`.`AP_SCHEDULED_SUBSCRIPTION`
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS `APP_MANAGER`.`AP_SCHEDULED_SUBSCRIPTION`(
|
||||||
|
`ID` INT NOT NULL AUTO_INCREMENT,
|
||||||
|
`TASK_NAME` VARCHAR(100) NOT NULL,
|
||||||
|
`APPLICATION_UUID` VARCHAR(36) NOT NULL,
|
||||||
|
`SUBSCRIBER_LIST` TEXT NOT NULL,
|
||||||
|
`STATUS` VARCHAR(15) NOT NULL,
|
||||||
|
`SCHEDULED_AT` TIMESTAMP NOT NULL,
|
||||||
|
`SCHEDULED_BY` VARCHAR(100) NOT NULL,
|
||||||
|
`SCHEDULED_TIMESTAMP` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`DELETED` BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
|
PRIMARY KEY (`ID`),
|
||||||
|
CONSTRAINT `fk_AP_SCHEDULED_SUBSCRIPTION_AP_APP_RELEASE`
|
||||||
|
FOREIGN KEY (`APPLICATION_UUID`)
|
||||||
|
REFERENCES `AP_APP_RELEASE` (`UUID`) ON DELETE NO ACTION ON UPDATE NO ACTION
|
||||||
|
)
|
||||||
|
ENGINE = InnoDB
|
||||||
|
DEFAULT CHARACTER SET = utf8;
|
||||||
|
|||||||
@ -365,3 +365,20 @@ CREATE TABLE APPM_PLATFORM_TAG (
|
|||||||
|
|
||||||
CREATE INDEX FK_APPM_PLATFORM_TAG_APP ON APPM_PLATFORM_TAG(PLATFORM_ID ASC)
|
CREATE INDEX FK_APPM_PLATFORM_TAG_APP ON APPM_PLATFORM_TAG(PLATFORM_ID ASC)
|
||||||
/
|
/
|
||||||
|
|
||||||
|
CREATE TABLE AP_SCHEDULED_SUBSCRIPTION (
|
||||||
|
ID number GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL,
|
||||||
|
TASK_NAME VARCHAR(100) NOT NULL,
|
||||||
|
APPLICATION_UUID VARCHAR(36) NOT NULL,
|
||||||
|
SUBSCRIBER_LIST VARCHAR(4000) NOT NULL,
|
||||||
|
STATUS VARCHAR(15) NOT NULL,
|
||||||
|
SCHEDULED_AT TIMESTAMP NOT NULL,
|
||||||
|
SCHEDULED_BY VARCHAR(100) NOT NULL,
|
||||||
|
SCHEDULED_TIMESTAMP TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
DELETED NUMBER(1) NOT_NULL DEFAULT 0,
|
||||||
|
PRIMARY KEY (ID),
|
||||||
|
CONSTRAINT FK_AP_SCHEDULED_SUBSCRIPTION_AP_APP_RELEASE
|
||||||
|
FOREIGN KEY (APPLICATION_UUID)
|
||||||
|
REFERENCES AP_APP_RELEASE (UUID)
|
||||||
|
)
|
||||||
|
/
|
||||||
|
|||||||
@ -253,3 +253,27 @@ CREATE TABLE IF NOT EXISTS APPM_RELEASE_PROPERTY (
|
|||||||
ON UPDATE NO ACTION);
|
ON UPDATE NO ACTION);
|
||||||
|
|
||||||
CREATE INDEX FK_RELEASE_PROPERTY_APPLICATION_RELEASE ON APPM_RELEASE_PROPERTY(APPLICATION_RELEASE_ID ASC);
|
CREATE INDEX FK_RELEASE_PROPERTY_APPLICATION_RELEASE ON APPM_RELEASE_PROPERTY(APPLICATION_RELEASE_ID ASC);
|
||||||
|
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS AP_SCHEDULED_SUBSCRIPTION;
|
||||||
|
DROP SEQUENCE IF EXISTS APPM_SCHEDULED_SUBSCRIPTION_PK_SEQ;
|
||||||
|
CREATE SEQUENCE APPM_SCHEDULED_SUBSCRIPTION_PK_SEQ;
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Table AP_SCHEDULED_SUBSCRIPTION
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS AP_SCHEDULED_SUBSCRIPTION(
|
||||||
|
ID INT DEFAULT NEXTVAL('APPM_SCHEDULED_SUBSCRIPTION_PK_SEQ') UNIQUE,
|
||||||
|
TASK_NAME VARCHAR(100) NOT NULL,
|
||||||
|
APPLICATION_UUID VARCHAR(36) NOT NULL,
|
||||||
|
SUBSCRIBER_LIST VARCHAR NOT NULL,
|
||||||
|
STATUS VARCHAR(15) NOT NULL,
|
||||||
|
SCHEDULED_AT TIMESTAMP NOT NULL,
|
||||||
|
SCHEDULED_BY VARCHAR(100) NOT NULL,
|
||||||
|
SCHEDULED_TIMESTAMP TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
DELETED BOOLEAN NOT NULL DEFAULT FALSE
|
||||||
|
PRIMARY KEY (ID),
|
||||||
|
CONSTRAINT FK_AP_SCHEDULED_SUBSCRIPTION_AP_APP_RELEASE
|
||||||
|
FOREIGN KEY (APPLICATION_UUID)
|
||||||
|
REFERENCES AP_APP_RELEASE (UUID) ON DELETE NO ACTION ON UPDATE NO ACTION
|
||||||
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user