Switched over to use the new jobs framework

This commit is contained in:
Alex Huang 2013-08-01 20:40:11 -07:00
parent dd0536f9d3
commit 8930cfa983
54 changed files with 439 additions and 3727 deletions

View File

@ -1,24 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async;
public enum AsyncInstanceCreateStatus {
Creating,
Created,
Corrupted,
Failed;
}

View File

@ -1,71 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async;
import org.apache.cloudstack.api.ApiCommandJobType;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
import java.util.Date;
public interface AsyncJob extends Identity, InternalIdentity {
long getUserId();
long getAccountId();
String getCmd();
int getCmdVersion();
String getCmdInfo();
int getCallbackType();
String getCallbackAddress();
int getStatus();
int getProcessStatus();
int getResultCode();
String getResult();
Long getInitMsid();
Long getCompleteMsid();
Date getCreated();
Date getLastUpdated();
Date getLastPolled();
Date getRemoved();
ApiCommandJobType getInstanceType();
Long getInstanceId();
String getSessionKey();
String getCmdOriginator();
boolean isFromPreviousSession();
SyncQueueItem getSyncSource();
}

View File

@ -1,26 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async;
public interface SyncQueueItem {
public final String AsyncJobContentType = "AsyncJob";
String getContentType();
Long getContentId();
}

View File

@ -19,8 +19,6 @@ package com.cloud.network.security;
import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity; import org.apache.cloudstack.api.InternalIdentity;
import com.cloud.async.AsyncInstanceCreateStatus;
public interface SecurityRule extends Identity, InternalIdentity { public interface SecurityRule extends Identity, InternalIdentity {
public static class SecurityRuleType { public static class SecurityRuleType {
@ -28,13 +26,13 @@ public interface SecurityRule extends Identity, InternalIdentity {
public static final SecurityRuleType EgressRule = new SecurityRuleType("egress"); public static final SecurityRuleType EgressRule = new SecurityRuleType("egress");
public SecurityRuleType(String type) { public SecurityRuleType(String type) {
this._type = type; _type = type;
} }
public String getType(){ public String getType(){
return _type; return _type;
} }
private String _type; private final String _type;
} }
long getSecurityGroupId(); long getSecurityGroupId();
@ -49,8 +47,6 @@ public interface SecurityRule extends Identity, InternalIdentity {
String getProtocol(); String getProtocol();
AsyncInstanceCreateStatus getCreateStatus();
Long getAllowedNetworkId(); Long getAllowedNetworkId();
String getAllowedSourceIpCidr(); String getAllowedSourceIpCidr();

View File

@ -16,10 +16,8 @@
// under the License. // under the License.
package org.apache.cloudstack.api; package org.apache.cloudstack.api;
import org.apache.cloudstack.api.response.AsyncJobResponse;
import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.context.CallContext;
import com.cloud.async.AsyncJob;
import com.cloud.user.User; import com.cloud.user.User;
/** /**
@ -33,7 +31,7 @@ public abstract class BaseAsyncCmd extends BaseCmd {
public static final String snapshotHostSyncObject = "snapshothost"; public static final String snapshotHostSyncObject = "snapshothost";
public static final String gslbSyncObject = "globalserverloadbalacner"; public static final String gslbSyncObject = "globalserverloadbalacner";
private AsyncJob job; private Object job;
@Parameter(name = "starteventid", type = CommandType.LONG) @Parameter(name = "starteventid", type = CommandType.LONG)
private Long startEventId; private Long startEventId;
@ -56,16 +54,8 @@ public abstract class BaseAsyncCmd extends BaseCmd {
*/ */
public abstract String getEventDescription(); public abstract String getEventDescription();
public ResponseObject getResponse(long jobId) {
AsyncJobResponse response = new AsyncJobResponse();
AsyncJob job = _entityMgr.findById(AsyncJob.class, jobId); public void setJob(Object job) {
response.setJobId(job.getUuid());
response.setResponseName(getCommandName());
return response;
}
public void setJob(AsyncJob job) {
this.job = job; this.job = job;
} }
@ -100,7 +90,7 @@ public abstract class BaseAsyncCmd extends BaseCmd {
return null; return null;
} }
public AsyncJob getJob() { public Object getJob() {
return job; return job;
} }

View File

@ -16,13 +16,9 @@
// under the License. // under the License.
package org.apache.cloudstack.api; package org.apache.cloudstack.api;
import org.apache.cloudstack.api.response.CreateCmdResponse;
import com.cloud.async.AsyncJob;
import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceAllocationException;
public abstract class BaseAsyncCreateCmd extends BaseAsyncCmd { public abstract class BaseAsyncCreateCmd extends BaseAsyncCmd {
@Parameter(name = "id", type = CommandType.LONG)
private Long id; private Long id;
private String uuid; private String uuid;
@ -45,15 +41,6 @@ public abstract class BaseAsyncCreateCmd extends BaseAsyncCmd {
this.uuid = uuid; this.uuid = uuid;
} }
public String getResponse(long jobId, String objectUuid) {
CreateCmdResponse response = new CreateCmdResponse();
AsyncJob job = _entityMgr.findById(AsyncJob.class, jobId);
response.setJobId(job.getUuid());
response.setId(objectUuid);
response.setResponseName(getCommandName());
return _responseGenerator.toSerializedString(response, getResponseType());
}
public String getCreateEventType() { public String getCreateEventType() {
return null; return null;
} }

View File

@ -16,80 +16,10 @@
// under the License. // under the License.
package org.apache.cloudstack.api; package org.apache.cloudstack.api;
import com.cloud.async.AsyncJob; import java.text.DecimalFormat;
import com.cloud.capacity.Capacity; import java.util.EnumSet;
import com.cloud.configuration.ResourceCount; import java.util.List;
import com.cloud.configuration.ResourceLimit; import java.util.Map;
import com.cloud.dc.DataCenter;
import com.cloud.dc.Pod;
import com.cloud.dc.StorageNetworkIpRange;
import com.cloud.dc.Vlan;
import com.cloud.domain.Domain;
import com.cloud.event.Event;
import com.cloud.host.Host;
import com.cloud.hypervisor.HypervisorCapabilities;
import com.cloud.network.GuestVlan;
import com.cloud.network.IpAddress;
import com.cloud.network.Network;
import com.cloud.network.Network.Service;
import com.cloud.network.Networks.IsolationType;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.PhysicalNetworkServiceProvider;
import com.cloud.network.PhysicalNetworkTrafficType;
import com.cloud.network.RemoteAccessVpn;
import com.cloud.network.Site2SiteCustomerGateway;
import com.cloud.network.Site2SiteVpnConnection;
import com.cloud.network.Site2SiteVpnGateway;
import com.cloud.network.VirtualRouterProvider;
import com.cloud.network.VpnUser;
import com.cloud.network.as.AutoScalePolicy;
import com.cloud.network.as.AutoScaleVmGroup;
import com.cloud.network.as.AutoScaleVmProfile;
import com.cloud.network.as.Condition;
import com.cloud.network.as.Counter;
import com.cloud.network.router.VirtualRouter;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.HealthCheckPolicy;
import com.cloud.network.rules.LoadBalancer;
import com.cloud.network.rules.PortForwardingRule;
import com.cloud.network.rules.StaticNatRule;
import com.cloud.network.rules.StickinessPolicy;
import com.cloud.network.security.SecurityGroup;
import com.cloud.network.security.SecurityRule;
import com.cloud.network.vpc.NetworkACL;
import com.cloud.network.vpc.NetworkACLItem;
import com.cloud.network.vpc.PrivateGateway;
import com.cloud.network.vpc.StaticRoute;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.VpcOffering;
import com.cloud.offering.DiskOffering;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.ServiceOffering;
import com.cloud.org.Cluster;
import com.cloud.projects.Project;
import com.cloud.projects.ProjectAccount;
import com.cloud.projects.ProjectInvitation;
import com.cloud.region.ha.GlobalLoadBalancerRule;
import com.cloud.server.ResourceTag;
import com.cloud.storage.GuestOS;
import com.cloud.storage.S3;
import com.cloud.storage.Snapshot;
import com.cloud.storage.StoragePool;
import com.cloud.storage.Swift;
import com.cloud.storage.Volume;
import com.cloud.storage.snapshot.SnapshotPolicy;
import com.cloud.storage.snapshot.SnapshotSchedule;
import com.cloud.template.VirtualMachineTemplate;
import com.cloud.user.Account;
import com.cloud.user.User;
import com.cloud.user.UserAccount;
import com.cloud.uservm.UserVm;
import com.cloud.utils.net.Ip;
import com.cloud.vm.InstanceGroup;
import com.cloud.vm.Nic;
import com.cloud.vm.NicSecondaryIp;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.snapshot.VMSnapshot;
import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.affinity.AffinityGroup;
import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.affinity.AffinityGroupResponse;
@ -189,12 +119,80 @@ import org.apache.cloudstack.region.PortableIpRange;
import org.apache.cloudstack.region.Region; import org.apache.cloudstack.region.Region;
import org.apache.cloudstack.usage.Usage; import org.apache.cloudstack.usage.Usage;
import com.cloud.capacity.Capacity;
import com.cloud.configuration.ResourceCount;
import com.cloud.configuration.ResourceLimit;
import com.cloud.dc.DataCenter;
import com.cloud.dc.Pod;
import com.cloud.dc.StorageNetworkIpRange;
import com.cloud.dc.Vlan;
import com.cloud.domain.Domain;
import com.cloud.event.Event;
import com.cloud.host.Host;
import com.cloud.hypervisor.HypervisorCapabilities;
import com.cloud.network.GuestVlan;
import com.cloud.network.IpAddress;
import com.cloud.network.Network;
import com.cloud.network.Network.Service;
import com.cloud.network.Networks.IsolationType;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.PhysicalNetworkServiceProvider;
import com.cloud.network.PhysicalNetworkTrafficType;
import com.cloud.network.RemoteAccessVpn;
import com.cloud.network.Site2SiteCustomerGateway;
import com.cloud.network.Site2SiteVpnConnection;
import com.cloud.network.Site2SiteVpnGateway;
import com.cloud.network.VirtualRouterProvider;
import com.cloud.network.VpnUser;
import com.cloud.network.as.AutoScalePolicy;
import com.cloud.network.as.AutoScaleVmGroup;
import com.cloud.network.as.AutoScaleVmProfile;
import com.cloud.network.as.Condition;
import com.cloud.network.as.Counter;
import com.cloud.network.router.VirtualRouter;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.HealthCheckPolicy;
import com.cloud.network.rules.LoadBalancer;
import com.cloud.network.rules.PortForwardingRule;
import com.cloud.network.rules.StaticNatRule;
import com.cloud.network.rules.StickinessPolicy;
import com.cloud.network.security.SecurityGroup;
import com.cloud.network.security.SecurityRule;
import com.cloud.network.vpc.NetworkACL;
import com.cloud.network.vpc.NetworkACLItem;
import com.cloud.network.vpc.PrivateGateway;
import com.cloud.network.vpc.StaticRoute;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.VpcOffering;
import com.cloud.offering.DiskOffering;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.ServiceOffering;
import com.cloud.org.Cluster;
import com.cloud.projects.Project;
import com.cloud.projects.ProjectAccount;
import com.cloud.projects.ProjectInvitation;
import com.cloud.region.ha.GlobalLoadBalancerRule;
import com.cloud.server.ResourceTag;
import com.cloud.storage.GuestOS;
import com.cloud.storage.ImageStore; import com.cloud.storage.ImageStore;
import com.cloud.storage.S3;
import java.text.DecimalFormat; import com.cloud.storage.Snapshot;
import java.util.EnumSet; import com.cloud.storage.StoragePool;
import java.util.List; import com.cloud.storage.Swift;
import java.util.Map; import com.cloud.storage.Volume;
import com.cloud.storage.snapshot.SnapshotPolicy;
import com.cloud.storage.snapshot.SnapshotSchedule;
import com.cloud.template.VirtualMachineTemplate;
import com.cloud.user.Account;
import com.cloud.user.User;
import com.cloud.user.UserAccount;
import com.cloud.uservm.UserVm;
import com.cloud.utils.net.Ip;
import com.cloud.vm.InstanceGroup;
import com.cloud.vm.Nic;
import com.cloud.vm.NicSecondaryIp;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.snapshot.VMSnapshot;
public interface ResponseGenerator { public interface ResponseGenerator {
UserResponse createUserResponse(UserAccount user); UserResponse createUserResponse(UserAccount user);
@ -304,8 +302,6 @@ public interface ResponseGenerator {
String toSerializedString(CreateCmdResponse response, String responseType); String toSerializedString(CreateCmdResponse response, String responseType);
AsyncJobResponse createAsyncJobResponse(AsyncJob job);
EventResponse createEventResponse(Event event); EventResponse createEventResponse(Event event);
//List<EventResponse> createEventResponse(EventJoinVO... events); //List<EventResponse> createEventResponse(EventJoinVO... events);

View File

@ -19,13 +19,12 @@ package org.apache.cloudstack.api.command.user.network;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.cloud.network.vpc.NetworkACL; import org.apache.commons.lang.StringUtils;
import com.cloud.network.vpc.NetworkACLItem; import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode; import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.BaseAsyncCreateCmd; import org.apache.cloudstack.api.BaseAsyncCreateCmd;
import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.ServerApiException;
@ -34,16 +33,10 @@ import org.apache.cloudstack.api.response.NetworkACLResponse;
import org.apache.cloudstack.api.response.NetworkResponse; import org.apache.cloudstack.api.response.NetworkResponse;
import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.context.CallContext;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import com.cloud.async.AsyncJob;
import com.cloud.event.EventTypes; import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.Network; import com.cloud.network.vpc.NetworkACLItem;
import com.cloud.network.vpc.Vpc;
import com.cloud.user.Account; import com.cloud.user.Account;
import com.cloud.utils.net.NetUtils; import com.cloud.utils.net.NetUtils;

View File

@ -16,8 +16,7 @@
// under the License. // under the License.
package org.apache.cloudstack.api.command.user.network; package org.apache.cloudstack.api.command.user.network;
import com.cloud.network.vpc.NetworkACLItem; import org.apache.log4j.Logger;
import com.cloud.user.Account;
import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiConstants;
@ -25,19 +24,13 @@ import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd; import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.AccountResponse;
import org.apache.cloudstack.api.response.FirewallRuleResponse;
import org.apache.cloudstack.api.response.NetworkACLItemResponse; import org.apache.cloudstack.api.response.NetworkACLItemResponse;
import org.apache.cloudstack.api.response.SuccessResponse; import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger;
import com.cloud.async.AsyncJob;
import com.cloud.event.EventTypes; import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.rules.FirewallRule; import com.cloud.user.Account;
@APICommand(name = "deleteNetworkACL", description="Deletes a Network ACL", responseObject=SuccessResponse.class) @APICommand(name = "deleteNetworkACL", description="Deletes a Network ACL", responseObject=SuccessResponse.class)
public class DeleteNetworkACLCmd extends BaseAsyncCmd { public class DeleteNetworkACLCmd extends BaseAsyncCmd {
@ -91,7 +84,7 @@ public class DeleteNetworkACLCmd extends BaseAsyncCmd {
if (result) { if (result) {
SuccessResponse response = new SuccessResponse(getCommandName()); SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response); setResponseObject(response);
} else { } else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete network ACL Item"); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete network ACL Item");
} }

View File

@ -16,23 +16,21 @@
// under the License. // under the License.
package org.apache.cloudstack.api.command.user.network; package org.apache.cloudstack.api.command.user.network;
import com.cloud.async.AsyncJob; import org.apache.log4j.Logger;
import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.vpc.NetworkACL;
import com.cloud.network.vpc.Vpc;
import com.cloud.user.Account;
import org.apache.cloudstack.api.*; import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.response.AccountResponse; import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.response.FirewallRuleResponse; import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.NetworkACLResponse; import org.apache.cloudstack.api.response.NetworkACLResponse;
import org.apache.cloudstack.api.response.SuccessResponse; import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger; import com.cloud.event.EventTypes;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.user.Account;
@APICommand(name = "deleteNetworkACLList", description="Deletes a Network ACL", responseObject=SuccessResponse.class) @APICommand(name = "deleteNetworkACLList", description="Deletes a Network ACL", responseObject=SuccessResponse.class)
public class DeleteNetworkACLListCmd extends BaseAsyncCmd { public class DeleteNetworkACLListCmd extends BaseAsyncCmd {
@ -86,7 +84,7 @@ public class DeleteNetworkACLListCmd extends BaseAsyncCmd {
if (result) { if (result) {
SuccessResponse response = new SuccessResponse(getCommandName()); SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response); setResponseObject(response);
} else { } else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete network ACL"); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete network ACL");
} }

View File

@ -16,27 +16,21 @@
// under the License. // under the License.
package org.apache.cloudstack.api.command.user.volume; package org.apache.cloudstack.api.command.user.volume;
import com.cloud.server.ResourceTag; import java.util.Collection;
import java.util.HashMap;
import org.apache.cloudstack.api.APICommand; import java.util.Iterator;
import org.apache.cloudstack.api.ApiConstants; import java.util.Map;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.api.response.VolumeResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.cloud.async.AsyncJob; import org.apache.cloudstack.api.APICommand;
import com.cloud.event.EventTypes; import org.apache.cloudstack.api.ApiConstants;
import com.cloud.storage.Volume; import org.apache.cloudstack.api.BaseAsyncCmd;
import com.cloud.user.Account; import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.response.SuccessResponse;
import java.util.*; import com.cloud.event.EventTypes;
import com.cloud.server.ResourceTag;
@APICommand(name = "addResourceDetail", description="Adds detail for the Resource.", responseObject=SuccessResponse.class) @APICommand(name = "addResourceDetail", description="Adds detail for the Resource.", responseObject=SuccessResponse.class)
public class AddResourceDetailCmd extends BaseAsyncCmd { public class AddResourceDetailCmd extends BaseAsyncCmd {
@ -113,6 +107,6 @@ public class AddResourceDetailCmd extends BaseAsyncCmd {
@Override @Override
public void execute(){ public void execute(){
_resourceMetaDataService.addResourceMetaData(getResourceId(), getResourceType(), getDetails()); _resourceMetaDataService.addResourceMetaData(getResourceId(), getResourceType(), getDetails());
this.setResponseObject(new SuccessResponse(getCommandName())); setResponseObject(new SuccessResponse(getCommandName()));
} }
} }

View File

@ -18,17 +18,17 @@ package org.apache.cloudstack.api.response;
import java.util.Date; import java.util.Date;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse; import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference; import org.apache.cloudstack.api.EntityReference;
import org.apache.cloudstack.api.ResponseObject; import org.apache.cloudstack.api.ResponseObject;
import org.apache.cloudstack.jobs.JobInfo;
import com.cloud.async.AsyncJob;
import com.cloud.serializer.Param; import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
@EntityReference(value=AsyncJob.class) @EntityReference(value = JobInfo.class)
@SuppressWarnings("unused")
public class AsyncJobResponse extends BaseResponse { public class AsyncJobResponse extends BaseResponse {
@SerializedName("accountid") @Param(description="the account that executed the async command") @SerializedName("accountid") @Param(description="the account that executed the async command")

View File

@ -22,18 +22,17 @@ import java.net.URL;
import java.util.List; import java.util.List;
import com.cloud.alert.Alert; import com.cloud.alert.Alert;
import com.cloud.async.AsyncJob;
public interface OperationsServices { public interface OperationsServices {
List<AsyncJob> listJobs(); // List<AsyncJob> listJobs();
//
List<AsyncJob> listJobsInProgress(); // List<AsyncJob> listJobsInProgress();
//
List<AsyncJob> listJobsCompleted(); // List<AsyncJob> listJobsCompleted();
//
List<AsyncJob> listJobsCompleted(Long from); // List<AsyncJob> listJobsCompleted(Long from);
//
List<AsyncJob> listJobsInWaiting(); // List<AsyncJob> listJobsInWaiting();
void cancelJob(String job); void cancelJob(String job);

View File

@ -38,10 +38,10 @@
<artifactId>cloud-framework-ipc</artifactId> <artifactId>cloud-framework-ipc</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-framework-jobs</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies> </dependencies>
<build>
<defaultGoal>install</defaultGoal>
<sourceDirectory>src</sourceDirectory>
<testSourceDirectory>test</testSourceDirectory>
</build>
</project> </project>

View File

@ -16,7 +16,8 @@
// under the License. // under the License.
package org.apache.cloudstack.context; package org.apache.cloudstack.context;
import com.cloud.async.AsyncJob; import org.apache.cloudstack.framework.jobs.AsyncJob;
import com.cloud.utils.db.Transaction; import com.cloud.utils.db.Transaction;
/** /**

View File

@ -18,15 +18,11 @@ package com.cloud.network.dao;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType; import javax.persistence.GenerationType;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.Table; import javax.persistence.Table;
import com.cloud.async.AsyncInstanceCreateStatus;
import com.google.gson.annotations.Expose;
import org.apache.cloudstack.api.InternalIdentity; import org.apache.cloudstack.api.InternalIdentity;
@Entity @Entity
@ -49,11 +45,6 @@ public class NetworkRuleConfigVO implements InternalIdentity {
@Column(name="protocol") @Column(name="protocol")
private String protocol; private String protocol;
@Expose
@Column(name="create_status", updatable = true, nullable=false)
@Enumerated(value=EnumType.STRING)
private AsyncInstanceCreateStatus createStatus;
public NetworkRuleConfigVO() {} public NetworkRuleConfigVO() {}
public NetworkRuleConfigVO(long securityGroupId, String publicPort, String privatePort, String protocol) { public NetworkRuleConfigVO(long securityGroupId, String publicPort, String privatePort, String protocol) {
@ -63,6 +54,7 @@ public class NetworkRuleConfigVO implements InternalIdentity {
this.protocol = protocol; this.protocol = protocol;
} }
@Override
public long getId() { public long getId() {
return id; return id;
} }
@ -82,12 +74,4 @@ public class NetworkRuleConfigVO implements InternalIdentity {
public String getProtocol() { public String getProtocol() {
return protocol; return protocol;
} }
public AsyncInstanceCreateStatus getCreateStatus() {
return createStatus;
}
public void setCreateStatus(AsyncInstanceCreateStatus createStatus) {
this.createStatus = createStatus;
}
} }

View File

@ -20,17 +20,11 @@ import java.util.UUID;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType; import javax.persistence.GenerationType;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.Table; import javax.persistence.Table;
import com.cloud.async.AsyncInstanceCreateStatus;
import com.google.gson.annotations.Expose;
import org.apache.cloudstack.api.InternalIdentity;
@Entity @Entity
@Table(name = ("security_group_rule")) @Table(name = ("security_group_rule"))
public class SecurityGroupRuleVO implements SecurityRule { public class SecurityGroupRuleVO implements SecurityRule {
@ -60,25 +54,20 @@ public class SecurityGroupRuleVO implements SecurityRule {
@Column(name = "allowed_ip_cidr", nullable = true) @Column(name = "allowed_ip_cidr", nullable = true)
private String allowedSourceIpCidr = null; private String allowedSourceIpCidr = null;
@Expose
@Column(name = "create_status", updatable = true, nullable = false)
@Enumerated(value = EnumType.STRING)
private AsyncInstanceCreateStatus createStatus;
@Column(name = "uuid") @Column(name = "uuid")
private String uuid; private String uuid;
public SecurityGroupRuleVO() { public SecurityGroupRuleVO() {
this.uuid = UUID.randomUUID().toString(); uuid = UUID.randomUUID().toString();
} }
public SecurityGroupRuleVO(SecurityRuleType type,long securityGroupId, int fromPort, int toPort, String protocol, long allowedNetworkId ) { public SecurityGroupRuleVO(SecurityRuleType type,long securityGroupId, int fromPort, int toPort, String protocol, long allowedNetworkId ) {
this.securityGroupId = securityGroupId; this.securityGroupId = securityGroupId;
this.startPort = fromPort; startPort = fromPort;
this.endPort = toPort; endPort = toPort;
this.protocol = protocol; this.protocol = protocol;
this.allowedNetworkId = allowedNetworkId; this.allowedNetworkId = allowedNetworkId;
this.uuid = UUID.randomUUID().toString(); uuid = UUID.randomUUID().toString();
if (type == SecurityRuleType.IngressRule) { if (type == SecurityRuleType.IngressRule) {
this.type = SecurityRuleType.IngressRule.getType(); this.type = SecurityRuleType.IngressRule.getType();
} else { } else {
@ -88,11 +77,11 @@ public class SecurityGroupRuleVO implements SecurityRule {
public SecurityGroupRuleVO(SecurityRuleType type,long securityGroupId, int fromPort, int toPort, String protocol, String allowedIpCidr) { public SecurityGroupRuleVO(SecurityRuleType type,long securityGroupId, int fromPort, int toPort, String protocol, String allowedIpCidr) {
this.securityGroupId = securityGroupId; this.securityGroupId = securityGroupId;
this.startPort = fromPort; startPort = fromPort;
this.endPort = toPort; endPort = toPort;
this.protocol = protocol; this.protocol = protocol;
this.allowedSourceIpCidr = allowedIpCidr; allowedSourceIpCidr = allowedIpCidr;
this.uuid = UUID.randomUUID().toString(); uuid = UUID.randomUUID().toString();
if (type == SecurityRuleType.IngressRule) { if (type == SecurityRuleType.IngressRule) {
this.type = SecurityRuleType.IngressRule.getType(); this.type = SecurityRuleType.IngressRule.getType();
} else { } else {
@ -115,8 +104,9 @@ public class SecurityGroupRuleVO implements SecurityRule {
return securityGroupId; return securityGroupId;
} }
@Override
public SecurityRuleType getRuleType() { public SecurityRuleType getRuleType() {
if ("ingress".equalsIgnoreCase(this.type)) if ("ingress".equalsIgnoreCase(type))
return SecurityRuleType.IngressRule; return SecurityRuleType.IngressRule;
else else
return SecurityRuleType.EgressRule; return SecurityRuleType.EgressRule;
@ -137,15 +127,6 @@ public class SecurityGroupRuleVO implements SecurityRule {
return protocol; return protocol;
} }
@Override
public AsyncInstanceCreateStatus getCreateStatus() {
return createStatus;
}
public void setCreateStatus(AsyncInstanceCreateStatus createStatus) {
this.createStatus = createStatus;
}
@Override @Override
public Long getAllowedNetworkId() { public Long getAllowedNetworkId() {
return allowedNetworkId; return allowedNetworkId;
@ -158,7 +139,7 @@ public class SecurityGroupRuleVO implements SecurityRule {
@Override @Override
public String getUuid() { public String getUuid() {
return this.uuid; return uuid;
} }
public void setUuid(String uuid) { public void setUuid(String uuid) {

View File

@ -52,10 +52,12 @@ import org.apache.cloudstack.api.response.UserResponse;
import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.api.response.VolumeResponse; import org.apache.cloudstack.api.response.VolumeResponse;
import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.framework.jobs.AsyncJob;
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
import org.apache.cloudstack.framework.jobs.dao.AsyncJobDao;
import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao; import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.springframework.stereotype.Component;
import com.cloud.api.query.dao.AccountJoinDao; import com.cloud.api.query.dao.AccountJoinDao;
import com.cloud.api.query.dao.AffinityGroupJoinDao; import com.cloud.api.query.dao.AffinityGroupJoinDao;
@ -98,10 +100,6 @@ import com.cloud.api.query.vo.TemplateJoinVO;
import com.cloud.api.query.vo.UserAccountJoinVO; import com.cloud.api.query.vo.UserAccountJoinVO;
import com.cloud.api.query.vo.UserVmJoinVO; import com.cloud.api.query.vo.UserVmJoinVO;
import com.cloud.api.query.vo.VolumeJoinVO; import com.cloud.api.query.vo.VolumeJoinVO;
import com.cloud.async.AsyncJob;
import com.cloud.async.AsyncJobManager;
import com.cloud.async.AsyncJobVO;
import com.cloud.async.dao.AsyncJobDao;
import com.cloud.capacity.CapacityVO; import com.cloud.capacity.CapacityVO;
import com.cloud.capacity.dao.CapacityDao; import com.cloud.capacity.dao.CapacityDao;
import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity; import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity;
@ -268,6 +266,7 @@ import com.cloud.user.dao.SSHKeyPairDao;
import com.cloud.user.dao.UserDao; import com.cloud.user.dao.UserDao;
import com.cloud.user.dao.UserStatisticsDao; import com.cloud.user.dao.UserStatisticsDao;
import com.cloud.uservm.UserVm; import com.cloud.uservm.UserVm;
import com.cloud.utils.EnumUtils;
import com.cloud.utils.NumbersUtil; import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair; import com.cloud.utils.Pair;
import com.cloud.vm.ConsoleProxyVO; import com.cloud.vm.ConsoleProxyVO;
@ -291,7 +290,6 @@ import com.cloud.vm.dao.VMInstanceDao;
import com.cloud.vm.snapshot.VMSnapshot; import com.cloud.vm.snapshot.VMSnapshot;
import com.cloud.vm.snapshot.dao.VMSnapshotDao; import com.cloud.vm.snapshot.dao.VMSnapshotDao;
@Component
public class ApiDBUtils { public class ApiDBUtils {
private static ManagementServer _ms; private static ManagementServer _ms;
static AsyncJobManager _asyncMgr; static AsyncJobManager _asyncMgr;
@ -405,8 +403,10 @@ public class ApiDBUtils {
static AccountService _accountService; static AccountService _accountService;
@Inject private ManagementServer ms; @Inject
@Inject public AsyncJobManager asyncMgr; private ManagementServer ms;
@Inject
public AsyncJobManager asyncMgr;
@Inject private SecurityGroupManager securityGroupMgr; @Inject private SecurityGroupManager securityGroupMgr;
@Inject private StorageManager storageMgr; @Inject private StorageManager storageMgr;
@Inject private UserVmManager userVmMgr; @Inject private UserVmManager userVmMgr;
@ -700,10 +700,6 @@ public class ApiDBUtils {
return _resourceLimitMgr.findCorrectResourceLimitForAccount(accountType, limit, type); return _resourceLimitMgr.findCorrectResourceLimitForAccount(accountType, limit, type);
} }
public static AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId) {
return _asyncMgr.findInstancePendingAsyncJob(instanceType, instanceId);
}
public static long getResourceCount(ResourceType type, long accountId) { public static long getResourceCount(ResourceType type, long accountId) {
AccountVO account = _accountDao.findById(accountId); AccountVO account = _accountDao.findById(accountId);
@ -1280,124 +1276,123 @@ public class ApiDBUtils {
} }
public static String findJobInstanceUuid(AsyncJob job){ public static String findJobInstanceUuid(AsyncJob job){
if ( job == null )
if ( job == null || job.getInstanceId() == null)
return null; return null;
String jobInstanceId = null;
ApiCommandJobType jobInstanceType = EnumUtils.fromString(ApiCommandJobType.class, job.getInstanceType(), ApiCommandJobType.None);
String jobInstanceUuid = null; if (jobInstanceType == ApiCommandJobType.Volume) {
if (job.getInstanceType() == ApiCommandJobType.Volume) {
VolumeVO volume = ApiDBUtils.findVolumeById(job.getInstanceId()); VolumeVO volume = ApiDBUtils.findVolumeById(job.getInstanceId());
if (volume != null) { if (volume != null) {
jobInstanceUuid = volume.getUuid(); jobInstanceId = volume.getUuid();
} }
} else if (job.getInstanceType() == ApiCommandJobType.Template || job.getInstanceType() == ApiCommandJobType.Iso) { } else if (jobInstanceType == ApiCommandJobType.Template || jobInstanceType == ApiCommandJobType.Iso) {
VMTemplateVO template = ApiDBUtils.findTemplateById(job.getInstanceId()); VMTemplateVO template = ApiDBUtils.findTemplateById(job.getInstanceId());
if (template != null) { if (template != null) {
jobInstanceUuid = template.getUuid(); jobInstanceId = template.getUuid();
} }
} else if (job.getInstanceType() == ApiCommandJobType.VirtualMachine || job.getInstanceType() == ApiCommandJobType.ConsoleProxy } else if (jobInstanceType == ApiCommandJobType.VirtualMachine || jobInstanceType == ApiCommandJobType.ConsoleProxy
|| job.getInstanceType() == ApiCommandJobType.SystemVm || job.getInstanceType() == ApiCommandJobType.DomainRouter) { || jobInstanceType == ApiCommandJobType.SystemVm || jobInstanceType == ApiCommandJobType.DomainRouter) {
VMInstanceVO vm = ApiDBUtils.findVMInstanceById(job.getInstanceId()); VMInstanceVO vm = ApiDBUtils.findVMInstanceById(job.getInstanceId());
if (vm != null) { if (vm != null) {
jobInstanceUuid = vm.getUuid(); jobInstanceId = vm.getUuid();
} }
} else if (job.getInstanceType() == ApiCommandJobType.Snapshot) { } else if (jobInstanceType == ApiCommandJobType.Snapshot) {
Snapshot snapshot = ApiDBUtils.findSnapshotById(job.getInstanceId()); Snapshot snapshot = ApiDBUtils.findSnapshotById(job.getInstanceId());
if (snapshot != null) { if (snapshot != null) {
jobInstanceUuid = snapshot.getUuid(); jobInstanceId = snapshot.getUuid();
} }
} else if (job.getInstanceType() == ApiCommandJobType.Host) { } else if (jobInstanceType == ApiCommandJobType.Host) {
Host host = ApiDBUtils.findHostById(job.getInstanceId()); Host host = ApiDBUtils.findHostById(job.getInstanceId());
if (host != null) { if (host != null) {
jobInstanceUuid = host.getUuid(); jobInstanceId = host.getUuid();
} }
} else if (job.getInstanceType() == ApiCommandJobType.StoragePool) { } else if (jobInstanceType == ApiCommandJobType.StoragePool) {
StoragePoolVO spool = ApiDBUtils.findStoragePoolById(job.getInstanceId()); StoragePoolVO spool = ApiDBUtils.findStoragePoolById(job.getInstanceId());
if (spool != null) { if (spool != null) {
jobInstanceUuid = spool.getUuid(); jobInstanceId = spool.getUuid();
} }
} else if (job.getInstanceType() == ApiCommandJobType.IpAddress) { } else if (jobInstanceType == ApiCommandJobType.IpAddress) {
IPAddressVO ip = ApiDBUtils.findIpAddressById(job.getInstanceId()); IPAddressVO ip = ApiDBUtils.findIpAddressById(job.getInstanceId());
if (ip != null) { if (ip != null) {
jobInstanceUuid = ip.getUuid(); jobInstanceId = ip.getUuid();
} }
} else if (job.getInstanceType() == ApiCommandJobType.SecurityGroup) { } else if (jobInstanceType == ApiCommandJobType.SecurityGroup) {
SecurityGroup sg = ApiDBUtils.findSecurityGroupById(job.getInstanceId()); SecurityGroup sg = ApiDBUtils.findSecurityGroupById(job.getInstanceId());
if (sg != null) { if (sg != null) {
jobInstanceUuid = sg.getUuid(); jobInstanceId = sg.getUuid();
} }
} else if (job.getInstanceType() == ApiCommandJobType.PhysicalNetwork) { } else if (jobInstanceType == ApiCommandJobType.PhysicalNetwork) {
PhysicalNetworkVO pnet = ApiDBUtils.findPhysicalNetworkById(job.getInstanceId()); PhysicalNetworkVO pnet = ApiDBUtils.findPhysicalNetworkById(job.getInstanceId());
if (pnet != null) { if (pnet != null) {
jobInstanceUuid = pnet.getUuid(); jobInstanceId = pnet.getUuid();
} }
} else if (job.getInstanceType() == ApiCommandJobType.TrafficType) { } else if (jobInstanceType == ApiCommandJobType.TrafficType) {
PhysicalNetworkTrafficTypeVO trafficType = ApiDBUtils.findPhysicalNetworkTrafficTypeById(job.getInstanceId()); PhysicalNetworkTrafficTypeVO trafficType = ApiDBUtils.findPhysicalNetworkTrafficTypeById(job.getInstanceId());
if (trafficType != null) { if (trafficType != null) {
jobInstanceUuid = trafficType.getUuid(); jobInstanceId = trafficType.getUuid();
} }
} else if (job.getInstanceType() == ApiCommandJobType.PhysicalNetworkServiceProvider) { } else if (jobInstanceType == ApiCommandJobType.PhysicalNetworkServiceProvider) {
PhysicalNetworkServiceProvider sp = ApiDBUtils.findPhysicalNetworkServiceProviderById(job.getInstanceId()); PhysicalNetworkServiceProvider sp = ApiDBUtils.findPhysicalNetworkServiceProviderById(job.getInstanceId());
if (sp != null) { if (sp != null) {
jobInstanceUuid = sp.getUuid(); jobInstanceId = sp.getUuid();
} }
} else if (job.getInstanceType() == ApiCommandJobType.FirewallRule) { } else if (jobInstanceType == ApiCommandJobType.FirewallRule) {
FirewallRuleVO fw = ApiDBUtils.findFirewallRuleById(job.getInstanceId()); FirewallRuleVO fw = ApiDBUtils.findFirewallRuleById(job.getInstanceId());
if (fw != null) { if (fw != null) {
jobInstanceUuid = fw.getUuid(); jobInstanceId = fw.getUuid();
} }
} else if (job.getInstanceType() == ApiCommandJobType.Account) { } else if (jobInstanceType == ApiCommandJobType.Account) {
Account acct = ApiDBUtils.findAccountById(job.getInstanceId()); Account acct = ApiDBUtils.findAccountById(job.getInstanceId());
if (acct != null) { if (acct != null) {
jobInstanceUuid = acct.getUuid(); jobInstanceId = acct.getUuid();
} }
} else if (job.getInstanceType() == ApiCommandJobType.User) { } else if (jobInstanceType == ApiCommandJobType.User) {
User usr = ApiDBUtils.findUserById(job.getInstanceId()); User usr = ApiDBUtils.findUserById(job.getInstanceId());
if (usr != null) { if (usr != null) {
jobInstanceUuid = usr.getUuid(); jobInstanceId = usr.getUuid();
} }
} else if (job.getInstanceType() == ApiCommandJobType.StaticRoute) { } else if (jobInstanceType == ApiCommandJobType.StaticRoute) {
StaticRouteVO route = ApiDBUtils.findStaticRouteById(job.getInstanceId()); StaticRouteVO route = ApiDBUtils.findStaticRouteById(job.getInstanceId());
if (route != null) { if (route != null) {
jobInstanceUuid = route.getUuid(); jobInstanceId = route.getUuid();
} }
} else if (job.getInstanceType() == ApiCommandJobType.PrivateGateway) { } else if (jobInstanceType == ApiCommandJobType.PrivateGateway) {
VpcGatewayVO gateway = ApiDBUtils.findVpcGatewayById(job.getInstanceId()); VpcGatewayVO gateway = ApiDBUtils.findVpcGatewayById(job.getInstanceId());
if (gateway != null) { if (gateway != null) {
jobInstanceUuid = gateway.getUuid(); jobInstanceId = gateway.getUuid();
} }
} else if (job.getInstanceType() == ApiCommandJobType.Counter) { } else if (jobInstanceType == ApiCommandJobType.Counter) {
CounterVO counter = ApiDBUtils.getCounter(job.getInstanceId()); CounterVO counter = ApiDBUtils.getCounter(job.getInstanceId());
if (counter != null) { if (counter != null) {
jobInstanceUuid = counter.getUuid(); jobInstanceId = counter.getUuid();
} }
} else if (job.getInstanceType() == ApiCommandJobType.Condition) { } else if (jobInstanceType == ApiCommandJobType.Condition) {
ConditionVO condition = ApiDBUtils.findConditionById(job.getInstanceId()); ConditionVO condition = ApiDBUtils.findConditionById(job.getInstanceId());
if (condition != null) { if (condition != null) {
jobInstanceUuid = condition.getUuid(); jobInstanceId = condition.getUuid();
} }
} else if (job.getInstanceType() == ApiCommandJobType.AutoScalePolicy) { } else if (jobInstanceType == ApiCommandJobType.AutoScalePolicy) {
AutoScalePolicyVO policy = ApiDBUtils.findAutoScalePolicyById(job.getInstanceId()); AutoScalePolicyVO policy = ApiDBUtils.findAutoScalePolicyById(job.getInstanceId());
if (policy != null) { if (policy != null) {
jobInstanceUuid = policy.getUuid(); jobInstanceId = policy.getUuid();
} }
} else if (job.getInstanceType() == ApiCommandJobType.AutoScaleVmProfile) { } else if (jobInstanceType == ApiCommandJobType.AutoScaleVmProfile) {
AutoScaleVmProfileVO profile = ApiDBUtils.findAutoScaleVmProfileById(job.getInstanceId()); AutoScaleVmProfileVO profile = ApiDBUtils.findAutoScaleVmProfileById(job.getInstanceId());
if (profile != null) { if (profile != null) {
jobInstanceUuid = profile.getUuid(); jobInstanceId = profile.getUuid();
} }
} else if (job.getInstanceType() == ApiCommandJobType.AutoScaleVmGroup) { } else if (jobInstanceType == ApiCommandJobType.AutoScaleVmGroup) {
AutoScaleVmGroupVO group = ApiDBUtils.findAutoScaleVmGroupById(job.getInstanceId()); AutoScaleVmGroupVO group = ApiDBUtils.findAutoScaleVmGroupById(job.getInstanceId());
if (group != null) { if (group != null) {
jobInstanceUuid = group.getUuid(); jobInstanceId = group.getUuid();
} }
} else if (job.getInstanceType() != ApiCommandJobType.None) { } else if (jobInstanceType != ApiCommandJobType.None) {
// TODO : when we hit here, we need to add instanceType -> UUID // TODO : when we hit here, we need to add instanceType -> UUID
// entity table mapping // entity table mapping
assert (false); assert (false);
} }
return jobInstanceUuid; return jobInstanceId;
} }
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////

View File

@ -34,7 +34,6 @@ import javax.annotation.PostConstruct;
import javax.inject.Inject; import javax.inject.Inject;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.InfrastructureEntity; import org.apache.cloudstack.acl.InfrastructureEntity;
@ -58,8 +57,9 @@ import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd;
import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd; import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd;
import org.apache.cloudstack.api.command.user.event.ListEventsCmd; import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.framework.jobs.AsyncJob;
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
import com.cloud.async.AsyncJobManager;
import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.InvalidParameterValueException;
import com.cloud.user.Account; import com.cloud.user.Account;
import com.cloud.user.AccountManager; import com.cloud.user.AccountManager;
@ -69,7 +69,6 @@ import com.cloud.utils.db.EntityManager;
import com.cloud.utils.exception.CSExceptionErrorCode; import com.cloud.utils.exception.CSExceptionErrorCode;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
@Component
public class ApiDispatcher { public class ApiDispatcher {
private static final Logger s_logger = Logger.getLogger(ApiDispatcher.class.getName()); private static final Logger s_logger = Logger.getLogger(ApiDispatcher.class.getName());
@ -129,7 +128,7 @@ public class ApiDispatcher {
} }
} }
public void dispatch(BaseCmd cmd, Map<String, String> params) throws Exception { public void dispatch(BaseCmd cmd, Map<String, String> params, boolean execute) throws Exception {
processParameters(cmd, params); processParameters(cmd, params);
CallContext ctx = CallContext.current(); CallContext ctx = CallContext.current();
@ -149,7 +148,11 @@ public class ApiDispatcher {
} }
if (queueSizeLimit != null) { if (queueSizeLimit != null) {
_asyncMgr.syncAsyncJobExecution(asyncCmd.getJob(), asyncCmd.getSyncObjType(), asyncCmd.getSyncObjId().longValue(), queueSizeLimit); if (!execute) {
// if we are not within async-execution context, enqueue the command
_asyncMgr.syncAsyncJobExecution((AsyncJob)asyncCmd.getJob(), asyncCmd.getSyncObjType(), asyncCmd.getSyncObjId().longValue(), queueSizeLimit);
return;
}
} else { } else {
s_logger.trace("The queue size is unlimited, skipping the synchronizing"); s_logger.trace("The queue size is unlimited, skipping the synchronizing");
} }
@ -193,8 +196,7 @@ public class ApiDispatcher {
Object paramObj = unpackedParams.get(parameterAnnotation.name()); Object paramObj = unpackedParams.get(parameterAnnotation.name());
if (paramObj == null) { if (paramObj == null) {
if (parameterAnnotation.required()) { if (parameterAnnotation.required()) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to execute API command " + cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to execute API command " + cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) + " due to missing parameter "
+ " due to missing parameter "
+ parameterAnnotation.name()); + parameterAnnotation.name());
} }
continue; continue;

View File

@ -32,7 +32,6 @@ import java.util.TimeZone;
import javax.inject.Inject; import javax.inject.Inject;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.ControlledEntity.ACLType;
@ -138,6 +137,8 @@ import org.apache.cloudstack.api.response.VpnUsersResponse;
import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.config.Configuration; import org.apache.cloudstack.config.Configuration;
import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.framework.jobs.AsyncJob;
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule; import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule;
import org.apache.cloudstack.region.PortableIp; import org.apache.cloudstack.region.PortableIp;
import org.apache.cloudstack.region.PortableIpRange; import org.apache.cloudstack.region.PortableIpRange;
@ -170,7 +171,6 @@ import com.cloud.api.query.vo.UserAccountJoinVO;
import com.cloud.api.query.vo.UserVmJoinVO; import com.cloud.api.query.vo.UserVmJoinVO;
import com.cloud.api.query.vo.VolumeJoinVO; import com.cloud.api.query.vo.VolumeJoinVO;
import com.cloud.api.response.ApiResponseSerializer; import com.cloud.api.response.ApiResponseSerializer;
import com.cloud.async.AsyncJob;
import com.cloud.capacity.Capacity; import com.cloud.capacity.Capacity;
import com.cloud.capacity.CapacityVO; import com.cloud.capacity.CapacityVO;
import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity; import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity;
@ -188,6 +188,8 @@ import com.cloud.dc.Vlan.VlanType;
import com.cloud.dc.VlanVO; import com.cloud.dc.VlanVO;
import com.cloud.domain.Domain; import com.cloud.domain.Domain;
import com.cloud.event.Event; import com.cloud.event.Event;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.host.Host; import com.cloud.host.Host;
import com.cloud.host.HostVO; import com.cloud.host.HostVO;
import com.cloud.hypervisor.HypervisorCapabilities; import com.cloud.hypervisor.HypervisorCapabilities;
@ -275,6 +277,7 @@ import com.cloud.storage.snapshot.SnapshotPolicy;
import com.cloud.storage.snapshot.SnapshotSchedule; import com.cloud.storage.snapshot.SnapshotSchedule;
import com.cloud.template.VirtualMachineTemplate; import com.cloud.template.VirtualMachineTemplate;
import com.cloud.user.Account; import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.User; import com.cloud.user.User;
import com.cloud.user.UserAccount; import com.cloud.user.UserAccount;
import com.cloud.uservm.UserVm; import com.cloud.uservm.UserVm;
@ -295,17 +298,21 @@ import com.cloud.vm.VirtualMachine.Type;
import com.cloud.vm.dao.NicSecondaryIpVO; import com.cloud.vm.dao.NicSecondaryIpVO;
import com.cloud.vm.snapshot.VMSnapshot; import com.cloud.vm.snapshot.VMSnapshot;
@Component
public class ApiResponseHelper implements ResponseGenerator { public class ApiResponseHelper implements ResponseGenerator {
public final Logger s_logger = Logger.getLogger(ApiResponseHelper.class); private static final Logger s_logger = Logger.getLogger(ApiResponseHelper.class);
private static final DecimalFormat s_percentFormat = new DecimalFormat("##.##"); private static final DecimalFormat s_percentFormat = new DecimalFormat("##.##");
@Inject @Inject
private final EntityManager _entityMgr = null; private EntityManager _entityMgr;
@Inject @Inject
private final UsageService _usageSvc = null; private UsageService _usageSvc;
@Inject NetworkModel _ntwkModel; @Inject NetworkModel _ntwkModel;
@Inject
protected AccountManager _accountMgr;
@Inject
protected AsyncJobManager _jobMgr;
@Override @Override
public UserResponse createUserResponse(User user) { public UserResponse createUserResponse(User user) {
UserAccountJoinVO vUser = ApiDBUtils.newUserView(user); UserAccountJoinVO vUser = ApiDBUtils.newUserView(user);
@ -1635,12 +1642,6 @@ public class ApiResponseHelper implements ResponseGenerator {
return ApiResponseSerializer.toSerializedString(response, responseType); return ApiResponseSerializer.toSerializedString(response, responseType);
} }
@Override
public AsyncJobResponse createAsyncJobResponse(AsyncJob job) {
AsyncJobJoinVO vJob = ApiDBUtils.newAsyncJobView(job);
return ApiDBUtils.newAsyncJobResponse(vJob);
}
@Override @Override
public List<TemplateResponse> createTemplateResponses(long templateId, Long snapshotId, Long volumeId, boolean readyOnly) { public List<TemplateResponse> createTemplateResponses(long templateId, Long snapshotId, Long volumeId, boolean readyOnly) {
VolumeVO volume = null; VolumeVO volume = null;
@ -1920,8 +1921,32 @@ public class ApiResponseHelper implements ResponseGenerator {
@Override @Override
public AsyncJobResponse queryJobResult(QueryAsyncJobResultCmd cmd) { public AsyncJobResponse queryJobResult(QueryAsyncJobResultCmd cmd) {
AsyncJob result = ApiDBUtils._asyncMgr.queryAsyncJobResult(cmd); Account caller = CallContext.current().getCallingAccount();
return createAsyncJobResponse(result);
AsyncJob job = _entityMgr.findById(AsyncJob.class, cmd.getId());
if (job == null) {
throw new InvalidParameterValueException("Unable to find a job by id " + cmd.getId());
}
User userJobOwner = _accountMgr.getUserIncludingRemoved(job.getUserId());
Account jobOwner = _accountMgr.getAccount(userJobOwner.getAccountId());
//check permissions
if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
//regular user can see only jobs he owns
if (caller.getId() != jobOwner.getId()) {
throw new PermissionDeniedException("Account " + caller + " is not authorized to see job id=" + job.getId());
}
} else if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
_accountMgr.checkAccess(caller, null, true, jobOwner);
}
return createAsyncJobResponse(_jobMgr.queryJob(cmd.getId(), true));
}
public AsyncJobResponse createAsyncJobResponse(AsyncJob job) {
AsyncJobJoinVO vJob = ApiDBUtils.newAsyncJobView(job);
return ApiDBUtils.newAsyncJobResponse(vJob);
} }
@Override @Override

View File

@ -16,16 +16,17 @@
// under the License. // under the License.
package com.cloud.api; package com.cloud.api;
import org.apache.cloudstack.api.ResponseObject;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.google.gson.Gson; import com.google.gson.Gson;
import org.apache.cloudstack.api.ResponseObject;
public class ApiSerializerHelper { public class ApiSerializerHelper {
public static final Logger s_logger = Logger.getLogger(ApiSerializerHelper.class.getName()); public static final Logger s_logger = Logger.getLogger(ApiSerializerHelper.class.getName());
public static String token = "/"; public static String token = "/";
public static String toSerializedStringOld(Object result) { public static String toSerializedString(Object result) {
if (result != null) { if (result != null) {
Class<?> clz = result.getClass(); Class<?> clz = result.getClass();
Gson gson = ApiGsonHelper.getBuilder().create(); Gson gson = ApiGsonHelper.getBuilder().create();

View File

@ -109,15 +109,16 @@ import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd; import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd; import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd; import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd;
import org.apache.cloudstack.api.response.AsyncJobResponse;
import org.apache.cloudstack.api.response.CreateCmdResponse;
import org.apache.cloudstack.api.response.ExceptionResponse; import org.apache.cloudstack.api.response.ExceptionResponse;
import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.framework.jobs.AsyncJob;
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
import com.cloud.api.response.ApiResponseSerializer; import com.cloud.api.response.ApiResponseSerializer;
import com.cloud.async.AsyncCommandQueued;
import com.cloud.async.AsyncJob;
import com.cloud.async.AsyncJobManager;
import com.cloud.async.AsyncJobVO;
import com.cloud.configuration.Config; import com.cloud.configuration.Config;
import com.cloud.configuration.ConfigurationVO; import com.cloud.configuration.ConfigurationVO;
import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.configuration.dao.ConfigurationDao;
@ -162,7 +163,8 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
@Inject private AccountManager _accountMgr; @Inject private AccountManager _accountMgr;
@Inject private DomainManager _domainMgr; @Inject private DomainManager _domainMgr;
@Inject private AsyncJobManager _asyncMgr; @Inject
private AsyncJobManager _asyncMgr;
@Inject private ConfigurationDao _configDao; @Inject private ConfigurationDao _configDao;
@Inject @Inject
private EntityManager _entityMgr; private EntityManager _entityMgr;
@ -170,8 +172,9 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
@Inject List<PluggableService> _pluggableServices; @Inject List<PluggableService> _pluggableServices;
@Inject List<APIChecker> _apiAccessCheckers; @Inject List<APIChecker> _apiAccessCheckers;
@Inject
protected ApiAsyncJobDispatcher _asyncDispatcher;
private static int _workerCount = 0; private static int _workerCount = 0;
private static ApiServer s_instance = null;
private static final DateFormat _dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); private static final DateFormat _dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
private static Map<String, Class<?>> _apiNameCmdClassMap = new HashMap<String, Class<?>>(); private static Map<String, Class<?>> _apiNameCmdClassMap = new HashMap<String, Class<?>>();
@ -182,17 +185,11 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
@PostConstruct @PostConstruct
void initComponent() { void initComponent() {
s_instance = this;
CallContext.init(_entityMgr); CallContext.init(_entityMgr);
} }
public static ApiServer getInstance() {
return s_instance;
}
@Override @Override
public boolean configure(String name, Map<String, Object> params) public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
throws ConfigurationException {
init(); init();
return true; return true;
} }
@ -428,10 +425,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
errorMsg = BaseCmd.USER_ERROR_MESSAGE; errorMsg = BaseCmd.USER_ERROR_MESSAGE;
} }
throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, errorMsg, ex); throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, errorMsg, ex);
} catch (AsyncCommandQueued ex){ } catch (ServerApiException ex) {
s_logger.error("unhandled exception executing api command: " + ((command == null) ? "null" : command[0]), ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Internal server error, unable to execute request.");
} catch (ServerApiException ex){
s_logger.info(ex.getDescription()); s_logger.info(ex.getDescription());
throw ex; throw ex;
} catch (Exception ex){ } catch (Exception ex){
@ -447,6 +441,24 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
return response; return response;
} }
private String getBaseAsyncResponse(long jobId, BaseAsyncCmd cmd) {
AsyncJobResponse response = new AsyncJobResponse();
AsyncJob job = _entityMgr.findById(AsyncJob.class, jobId);
response.setJobId(job.getUuid());
response.setResponseName(cmd.getCommandName());
return ApiResponseSerializer.toSerializedString(response, cmd.getResponseType());
}
private String getBaseAsyncCreateResponse(long jobId, BaseAsyncCreateCmd cmd, String objectUuid) {
CreateCmdResponse response = new CreateCmdResponse();
AsyncJob job = _entityMgr.findById(AsyncJob.class, jobId);
response.setJobId(job.getUuid());
response.setId(objectUuid);
response.setResponseName(cmd.getCommandName());
return ApiResponseSerializer.toSerializedString(response, cmd.getResponseType());
}
private String queueCommand(BaseCmd cmdObj, Map<String, String> params) throws Exception { private String queueCommand(BaseCmd cmdObj, Map<String, String> params) throws Exception {
CallContext ctx = CallContext.current(); CallContext ctx = CallContext.current();
Long callerUserId = ctx.getCallingUserId(); Long callerUserId = ctx.getCallingUserId();
@ -495,8 +507,10 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
params.put("cmdEventType", asyncCmd.getEventType().toString()); params.put("cmdEventType", asyncCmd.getEventType().toString());
Long instanceId = (objectId == null) ? asyncCmd.getInstanceId() : objectId; Long instanceId = (objectId == null) ? asyncCmd.getInstanceId() : objectId;
AsyncJobVO job = new AsyncJobVO(callerUserId, caller.getId(), cmdObj.getClass().getName(), AsyncJobVO job = new AsyncJobVO(ctx.getContextId(), callerUserId, caller.getId(), cmdObj.getClass().getName(),
ApiGsonHelper.getBuilder().create().toJson(params), instanceId, asyncCmd.getInstanceType()); ApiGsonHelper.getBuilder().create().toJson(params), instanceId,
asyncCmd.getInstanceType() != null ? asyncCmd.getInstanceType().toString() : null);
job.setDispatcher(_asyncDispatcher.getName());
long jobId = _asyncMgr.submitAsyncJob(job); long jobId = _asyncMgr.submitAsyncJob(job);
@ -508,13 +522,13 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
if (objectId != null) { if (objectId != null) {
String objUuid = (objectUuid == null) ? objectId.toString() : objectUuid; String objUuid = (objectUuid == null) ? objectId.toString() : objectUuid;
return ((BaseAsyncCreateCmd) asyncCmd).getResponse(jobId, objUuid); return getBaseAsyncCreateResponse(jobId, (BaseAsyncCreateCmd)asyncCmd, objUuid);
}
SerializationContext.current().setUuidTranslation(true);
return ApiResponseSerializer.toSerializedString(asyncCmd.getResponse(jobId), asyncCmd.getResponseType());
} else { } else {
_dispatcher.dispatch(cmdObj, params); SerializationContext.current().setUuidTranslation(true);
return getBaseAsyncResponse(jobId, asyncCmd);
}
} else {
_dispatcher.dispatch(cmdObj, params, false);
// if the command is of the listXXXCommand, we will need to also return the // if the command is of the listXXXCommand, we will need to also return the
// the job id and status if possible // the job id and status if possible
@ -552,9 +566,9 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
// list all jobs for ROOT admin // list all jobs for ROOT admin
if (account.getType() == Account.ACCOUNT_TYPE_ADMIN) { if (account.getType() == Account.ACCOUNT_TYPE_ADMIN) {
jobs = _asyncMgr.findInstancePendingAsyncJobs(command.getInstanceType(), null); jobs = _asyncMgr.findInstancePendingAsyncJobs(command.getInstanceType().toString(), null);
} else { } else {
jobs = _asyncMgr.findInstancePendingAsyncJobs(command.getInstanceType(), account.getId()); jobs = _asyncMgr.findInstancePendingAsyncJobs(command.getInstanceType().toString(), account.getId());
} }
if (jobs.size() == 0) { if (jobs.size() == 0) {
@ -567,16 +581,14 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
continue; continue;
} }
String instanceUuid = ApiDBUtils.findJobInstanceUuid(job); String instanceUuid = ApiDBUtils.findJobInstanceUuid(job);
if (instanceUuid != null) {
objectJobMap.put(instanceUuid, job); objectJobMap.put(instanceUuid, job);
} }
}
for (ResponseObject response : responses) { for (ResponseObject response : responses) {
if (response.getObjectId() != null && objectJobMap.containsKey(response.getObjectId())) { if (response.getObjectId() != null && objectJobMap.containsKey(response.getObjectId())) {
AsyncJob job = objectJobMap.get(response.getObjectId()); AsyncJob job = objectJobMap.get(response.getObjectId());
response.setJobId(job.getUuid()); response.setJobId(job.getUuid());
response.setJobStatus(job.getStatus()); response.setJobStatus(job.getStatus().ordinal());
} }
} }
} }

View File

@ -16,12 +16,10 @@
// under the License. // under the License.
package com.cloud.api.query.dao; package com.cloud.api.query.dao;
import java.util.List;
import org.apache.cloudstack.api.response.AsyncJobResponse; import org.apache.cloudstack.api.response.AsyncJobResponse;
import org.apache.cloudstack.framework.jobs.AsyncJob;
import com.cloud.api.query.vo.AsyncJobJoinVO; import com.cloud.api.query.vo.AsyncJobJoinVO;
import com.cloud.async.AsyncJob;
import com.cloud.utils.db.GenericDao; import com.cloud.utils.db.GenericDao;
public interface AsyncJobJoinDao extends GenericDao<AsyncJobJoinVO, Long> { public interface AsyncJobJoinDao extends GenericDao<AsyncJobJoinVO, Long> {

View File

@ -22,15 +22,15 @@ import java.util.List;
import javax.ejb.Local; import javax.ejb.Local;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.api.ResponseObject;
import org.apache.cloudstack.api.response.AsyncJobResponse;
import org.apache.cloudstack.framework.jobs.AsyncJob;
import com.cloud.api.ApiSerializerHelper; import com.cloud.api.ApiSerializerHelper;
import com.cloud.api.SerializationContext; import com.cloud.api.SerializationContext;
import com.cloud.api.query.vo.AsyncJobJoinVO; import com.cloud.api.query.vo.AsyncJobJoinVO;
import com.cloud.async.AsyncJob;
import org.apache.cloudstack.api.ResponseObject;
import org.apache.cloudstack.api.response.AsyncJobResponse;
import org.springframework.stereotype.Component;
import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria;
@ -40,7 +40,7 @@ import com.cloud.utils.db.SearchCriteria;
public class AsyncJobJoinDaoImpl extends GenericDaoBase<AsyncJobJoinVO, Long> implements AsyncJobJoinDao { public class AsyncJobJoinDaoImpl extends GenericDaoBase<AsyncJobJoinVO, Long> implements AsyncJobJoinDao {
public static final Logger s_logger = Logger.getLogger(AsyncJobJoinDaoImpl.class); public static final Logger s_logger = Logger.getLogger(AsyncJobJoinDaoImpl.class);
private SearchBuilder<AsyncJobJoinVO> jobIdSearch; private final SearchBuilder<AsyncJobJoinVO> jobIdSearch;
protected AsyncJobJoinDaoImpl() { protected AsyncJobJoinDaoImpl() {
@ -49,7 +49,7 @@ public class AsyncJobJoinDaoImpl extends GenericDaoBase<AsyncJobJoinVO, Long> im
jobIdSearch.and("id", jobIdSearch.entity().getId(), SearchCriteria.Op.EQ); jobIdSearch.and("id", jobIdSearch.entity().getId(), SearchCriteria.Op.EQ);
jobIdSearch.done(); jobIdSearch.done();
this._count = "select count(distinct id) from async_job_view WHERE "; _count = "select count(distinct id) from async_job_view WHERE ";
} }

View File

@ -1,35 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async;
import com.cloud.utils.SerialVersionUID;
import com.cloud.utils.exception.CloudRuntimeException;
public class AsyncCommandQueued extends CloudRuntimeException {
private static final long serialVersionUID = SerialVersionUID.AsyncCommandQueued;
private SyncQueueVO _queue = null;
public AsyncCommandQueued(SyncQueueVO queue, String msg) {
super(msg);
_queue = queue;
}
public SyncQueueVO getQueue() {
return _queue;
}
}

View File

@ -1,39 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async;
public interface AsyncJobExecutor {
public AsyncJobManager getAsyncJobMgr();
public void setAsyncJobMgr(AsyncJobManager asyncMgr);
public SyncQueueItemVO getSyncSource();
public void setSyncSource(SyncQueueItemVO syncSource);
public AsyncJobVO getJob();
public void setJob(AsyncJobVO job);
public void setFromPreviousSession(boolean value);
public boolean isFromPreviousSession();
/**
*
* otherwise return false and once the executor finally has completed with the sync source,
* it needs to call AsyncJobManager.releaseSyncSource
*
* if executor does not have a sync source, always return true
*/
public boolean execute();
}

View File

@ -1,54 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async;
import com.cloud.agent.AgentManager;
import com.cloud.async.dao.AsyncJobDao;
import com.cloud.event.dao.EventDao;
import com.cloud.network.NetworkModel;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.server.ManagementServer;
import com.cloud.storage.StorageManager;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.snapshot.SnapshotManager;
import com.cloud.user.AccountManager;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserDao;
import com.cloud.utils.component.Manager;
import com.cloud.vm.UserVmManager;
import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.UserVmDao;
public interface AsyncJobExecutorContext extends Manager {
public ManagementServer getManagementServer();
public AgentManager getAgentMgr();
public NetworkModel getNetworkMgr();
public UserVmManager getVmMgr();
public SnapshotManager getSnapshotMgr();
public AccountManager getAccountMgr();
public StorageManager getStorageMgr();
public EventDao getEventDao();
public UserVmDao getVmDao();
public AccountDao getAccountDao();
public VolumeDao getVolumeDao();
public DomainRouterDao getRouterDao();
public IPAddressDao getIpAddressDao();
public AsyncJobDao getJobDao();
public UserDao getUserDao();
public VirtualMachineManager getItMgr();
}

View File

@ -1,146 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async;
import javax.ejb.Local;
import javax.inject.Inject;
import org.springframework.stereotype.Component;
import com.cloud.agent.AgentManager;
import com.cloud.async.dao.AsyncJobDao;
import com.cloud.event.dao.EventDao;
import com.cloud.network.NetworkModel;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.server.ManagementServer;
import com.cloud.storage.StorageManager;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.snapshot.SnapshotManager;
import com.cloud.user.AccountManager;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserDao;
import com.cloud.utils.component.ManagerBase;
import com.cloud.vm.UserVmManager;
import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.UserVmDao;
@Component
@Local(value={AsyncJobExecutorContext.class})
public class AsyncJobExecutorContextImpl extends ManagerBase implements AsyncJobExecutorContext {
@Inject private AgentManager _agentMgr;
@Inject private NetworkModel _networkMgr;
@Inject private UserVmManager _vmMgr;
@Inject private SnapshotManager _snapMgr;
@Inject private AccountManager _accountMgr;
@Inject private StorageManager _storageMgr;
@Inject private EventDao _eventDao;
@Inject private UserVmDao _vmDao;
@Inject private AccountDao _accountDao;
@Inject private VolumeDao _volumeDao;
@Inject private DomainRouterDao _routerDao;
@Inject private IPAddressDao _ipAddressDao;
@Inject private AsyncJobDao _jobDao;
@Inject private UserDao _userDao;
@Inject private VirtualMachineManager _itMgr;
@Inject private ManagementServer _managementServer;
@Override
public ManagementServer getManagementServer() {
return _managementServer;
}
@Override
public AgentManager getAgentMgr() {
return _agentMgr;
}
@Override
public NetworkModel getNetworkMgr() {
return _networkMgr;
}
@Override
public UserVmManager getVmMgr() {
return _vmMgr;
}
@Override
public StorageManager getStorageMgr() {
return _storageMgr;
}
/**server/src/com/cloud/async/AsyncJobExecutorContext.java
* @return the _snapMgr
*/
@Override
public SnapshotManager getSnapshotMgr() {
return _snapMgr;
}
@Override
public AccountManager getAccountMgr() {
return _accountMgr;
}
@Override
public EventDao getEventDao() {
return _eventDao;
}
@Override
public UserVmDao getVmDao() {
return _vmDao;
}
@Override
public AccountDao getAccountDao() {
return _accountDao;
}
@Override
public VolumeDao getVolumeDao() {
return _volumeDao;
}
@Override
public DomainRouterDao getRouterDao() {
return _routerDao;
}
@Override
public IPAddressDao getIpAddressDao() {
return _ipAddressDao;
}
@Override
public AsyncJobDao getJobDao() {
return _jobDao;
}
@Override
public UserDao getUserDao() {
return _userDao;
}
@Override
public VirtualMachineManager getItMgr() {
return _itMgr;
}
}

View File

@ -1,37 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async;
public interface AsyncJobMBean {
public long getAccountId();
public long getUserId();
public String getCmd();
public String getCmdInfo();
public String getStatus();
public int getProcessStatus();
public int getResultCode();
public String getResult();
public String getInstanceType();
public String getInstanceId();
public String getInitMsid();
public String getCreateTime();
public String getLastUpdateTime();
public String getLastPollTime();
public String getSyncQueueId();
public String getSyncQueueContentType();
public String getSyncQueueContentId();
}

View File

@ -1,144 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async;
import java.util.Date;
import java.util.TimeZone;
import javax.management.StandardMBean;
import com.cloud.utils.DateUtil;
public class AsyncJobMBeanImpl extends StandardMBean implements AsyncJobMBean {
private AsyncJobVO _jobVo;
public AsyncJobMBeanImpl(AsyncJobVO jobVo) {
super(AsyncJobMBean.class, false);
_jobVo = jobVo;
}
public long getAccountId() {
return _jobVo.getAccountId();
}
public long getUserId() {
return _jobVo.getUserId();
}
public String getCmd() {
return _jobVo.getCmd();
}
public String getCmdInfo() {
return _jobVo.getCmdInfo();
}
public String getStatus() {
int jobStatus = _jobVo.getStatus();
switch(jobStatus) {
case AsyncJobResult.STATUS_SUCCEEDED :
return "Completed";
case AsyncJobResult.STATUS_IN_PROGRESS:
return "In preogress";
case AsyncJobResult.STATUS_FAILED:
return "failed";
}
return "Unknow";
}
public int getProcessStatus() {
return _jobVo.getProcessStatus();
}
public int getResultCode() {
return _jobVo.getResultCode();
}
public String getResult() {
return _jobVo.getResult();
}
public String getInstanceType() {
if(_jobVo.getInstanceType() != null)
return _jobVo.getInstanceType().toString();
return "N/A";
}
public String getInstanceId() {
if(_jobVo.getInstanceId() != null)
return String.valueOf(_jobVo.getInstanceId());
return "N/A";
}
public String getInitMsid() {
if(_jobVo.getInitMsid() != null) {
return String.valueOf(_jobVo.getInitMsid());
}
return "N/A";
}
public String getCreateTime() {
Date time = _jobVo.getCreated();
if(time != null)
return DateUtil.getDateDisplayString(TimeZone.getDefault(), time);
return "N/A";
}
public String getLastUpdateTime() {
Date time = _jobVo.getLastUpdated();
if(time != null)
return DateUtil.getDateDisplayString(TimeZone.getDefault(), time);
return "N/A";
}
public String getLastPollTime() {
Date time = _jobVo.getLastPolled();
if(time != null)
return DateUtil.getDateDisplayString(TimeZone.getDefault(), time);
return "N/A";
}
public String getSyncQueueId() {
SyncQueueItemVO item = _jobVo.getSyncSource();
if(item != null && item.getQueueId() != null) {
return String.valueOf(item.getQueueId());
}
return "N/A";
}
public String getSyncQueueContentType() {
SyncQueueItemVO item = _jobVo.getSyncSource();
if(item != null) {
return item.getContentType();
}
return "N/A";
}
public String getSyncQueueContentId() {
SyncQueueItemVO item = _jobVo.getSyncSource();
if(item != null && item.getContentId() != null) {
return String.valueOf(item.getContentId());
}
return "N/A";
}
}

View File

@ -1,52 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async;
import java.util.List;
import org.apache.cloudstack.api.ApiCommandJobType;
import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
import com.cloud.utils.component.Manager;
public interface AsyncJobManager extends Manager {
public AsyncJobExecutorContext getExecutorContext();
public AsyncJobVO getAsyncJob(long jobId);
public AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId);
public List<? extends AsyncJob> findInstancePendingAsyncJobs(ApiCommandJobType instanceType, Long accountId);
public long submitAsyncJob(AsyncJobVO job);
public long submitAsyncJob(AsyncJobVO job, boolean scheduleJobExecutionInContext);
public AsyncJobResult queryAsyncJobResult(long jobId);
public void completeAsyncJob(long jobId, int jobStatus, int resultCode, Object resultObject);
public void updateAsyncJobStatus(long jobId, int processStatus, Object resultObject);
public void updateAsyncJobAttachment(long jobId, String instanceType, Long instanceId);
public void releaseSyncSource(AsyncJobExecutor executor);
public void syncAsyncJobExecution(AsyncJob job, String syncObjType, long syncObjId, long queueSizeLimit);
/**
* Queries for the status or final result of an async job.
* @param cmd the command that specifies the job id
* @return an async-call result object
*/
public AsyncJob queryAsyncJobResult(QueryAsyncJobResultCmd cmd);
}

View File

@ -1,887 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async;
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Type;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.apache.log4j.NDC;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.stereotype.Component;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.cloudstack.api.ApiCommandJobType;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
import org.apache.cloudstack.api.response.ExceptionResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.framework.events.EventBus;
import org.apache.cloudstack.framework.events.EventBusException;
import org.apache.cloudstack.utils.identity.ManagementServerNode;
import com.cloud.api.ApiDBUtils;
import com.cloud.api.ApiDispatcher;
import com.cloud.api.ApiGsonHelper;
import com.cloud.api.ApiSerializerHelper;
import com.cloud.async.dao.AsyncJobDao;
import com.cloud.cluster.ClusterManagerListener;
import com.cloud.cluster.ManagementServerHost;
import com.cloud.configuration.Config;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.EventCategory;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.server.ManagementServer;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.User;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.DateUtil;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.PropertiesUtil;
import com.cloud.utils.component.ComponentContext;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.EntityManager;
import com.cloud.utils.db.GlobalLock;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.exception.ExceptionUtil;
import com.cloud.utils.mgmt.JmxUtil;
@Component
@Local(value={AsyncJobManager.class})
public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, ClusterManagerListener {
public static final Logger s_logger = Logger.getLogger(AsyncJobManagerImpl.class.getName());
private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 3; // 3 seconds
private static final int MAX_ONETIME_SCHEDULE_SIZE = 50;
private static final int HEARTBEAT_INTERVAL = 2000;
private static final int GC_INTERVAL = 10000; // 10 seconds
@Inject private AsyncJobExecutorContext _context;
@Inject private SyncQueueManager _queueMgr;
@Inject private AccountManager _accountMgr;
@Inject private AccountDao _accountDao;
@Inject private AsyncJobDao _jobDao;
@Inject private ConfigurationDao _configDao;
@Inject private DomainDao _domainDao;
private long _jobExpireSeconds = 86400; // 1 day
private long _jobCancelThresholdSeconds = 3600; // 1 hour (for cancelling the jobs blocking other jobs)
@Inject
private EntityManager _entityMgr;
@Inject private ApiDispatcher _dispatcher;
private final ScheduledExecutorService _heartbeatScheduler =
Executors.newScheduledThreadPool(1, new NamedThreadFactory("AsyncJobMgr-Heartbeat"));
private ExecutorService _executor;
@Override
public AsyncJobExecutorContext getExecutorContext() {
return _context;
}
@Override
public AsyncJobVO getAsyncJob(long jobId) {
return _jobDao.findById(jobId);
}
@Override
public AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId) {
return _jobDao.findInstancePendingAsyncJob(instanceType, instanceId);
}
@Override
public List<AsyncJobVO> findInstancePendingAsyncJobs(ApiCommandJobType instanceType, Long accountId) {
return _jobDao.findInstancePendingAsyncJobs(instanceType, accountId);
}
private void publishOnEventBus(AsyncJobVO job, String jobEvent) {
EventBus eventBus = null;
try {
eventBus = ComponentContext.getComponent(EventBus.class);
} catch(NoSuchBeanDefinitionException nbe) {
return; // no provider is configured to provide events bus, so just return
}
// Get the event type from the cmdInfo json string
String info = job.getCmdInfo();
String cmdEventType;
if ( info == null ) {
cmdEventType = "unknown";
} else {
String marker = "\"cmdEventType\"";
int begin = info.indexOf(marker);
cmdEventType = info.substring(begin + marker.length() + 2, info.indexOf(",", begin) - 1);
}
// For some reason, the instanceType / instanceId are not abstract, which means we may get null values.
org.apache.cloudstack.framework.events.Event event = new org.apache.cloudstack.framework.events.Event(
ManagementServer.Name,
EventCategory.ASYNC_JOB_CHANGE_EVENT.getName(),
jobEvent,
( job.getInstanceType() != null ? job.getInstanceType().toString() : "unknown" ), null);
User userJobOwner = _accountMgr.getUserIncludingRemoved(job.getUserId());
Account jobOwner = _accountMgr.getAccount(userJobOwner.getAccountId());
Map<String, String> eventDescription = new HashMap<String, String>();
eventDescription.put("command", job.getCmd());
eventDescription.put("user", userJobOwner.getUuid());
eventDescription.put("account", jobOwner.getUuid());
eventDescription.put("processStatus", "" + job.getProcessStatus());
eventDescription.put("resultCode", "" + job.getResultCode());
eventDescription.put("instanceUuid", ApiDBUtils.findJobInstanceUuid(job));
eventDescription.put("instanceType", ( job.getInstanceType() != null ? job.getInstanceType().toString() : "unknown" ) );
eventDescription.put("commandEventType", cmdEventType);
eventDescription.put("jobId", job.getUuid());
// If the event.accountinfo boolean value is set, get the human readable value for the username / domainname
Map<String, String> configs = _configDao.getConfiguration("management-server", new HashMap<String, String>());
if ( Boolean.valueOf(configs.get("event.accountinfo")) ) {
DomainVO domain = _domainDao.findById(jobOwner.getDomainId());
eventDescription.put("username", userJobOwner.getUsername());
eventDescription.put("domainname", domain.getName());
}
event.setDescription(eventDescription);
try {
eventBus.publish(event);
} catch (EventBusException evx) {
String errMsg = "Failed to publish async job event on the the event bus.";
s_logger.warn(errMsg, evx);
throw new CloudRuntimeException(errMsg);
}
}
@Override
public long submitAsyncJob(AsyncJobVO job) {
return submitAsyncJob(job, false);
}
@Override @DB
public long submitAsyncJob(AsyncJobVO job, boolean scheduleJobExecutionInContext) {
Transaction txt = Transaction.currentTxn();
try {
txt.start();
job.setInitMsid(getMsid());
_jobDao.persist(job);
txt.commit();
// no sync source originally
job.setSyncSource(null);
scheduleExecution(job, scheduleJobExecutionInContext);
if(s_logger.isDebugEnabled()) {
s_logger.debug("submit async job-" + job.getId() + " = [ " + job.getUuid() + " ], details: " + job.toString());
}
publishOnEventBus(job, "submit");
return job.getId();
} catch(Exception e) {
txt.rollback();
String errMsg = "Unable to schedule async job for command " + job.getCmd() + ", unexpected exception.";
s_logger.warn(errMsg, e);
throw new CloudRuntimeException(errMsg);
}
}
@Override @DB
public void completeAsyncJob(long jobId, int jobStatus, int resultCode, Object resultObject) {
AsyncJobVO job = _jobDao.findById(jobId);
String jobUuid = null;
if (job != null) {
jobUuid = job.getUuid();
if(s_logger.isDebugEnabled()) {
s_logger.debug("Complete async job-" + jobId + " = [ " + jobUuid + " ], jobStatus: " + jobStatus +
", resultCode: " + resultCode + ", result: " + resultObject);
}
} else {
if(s_logger.isDebugEnabled()) {
s_logger.debug("job-" + jobId + " no longer exists, we just log completion info here. " + jobStatus +
", resultCode: " + resultCode + ", result: " + resultObject);
}
return;
}
Transaction txt = Transaction.currentTxn();
try {
txt.start();
job.setCompleteMsid(getMsid());
job.setStatus(jobStatus);
job.setResultCode(resultCode);
publishOnEventBus(job, "complete"); // publish before the instance type and ID are wiped out
// reset attached object
job.setInstanceType(null);
job.setInstanceId(null);
if (resultObject != null) {
job.setResult(ApiSerializerHelper.toSerializedStringOld(resultObject));
}
job.setLastUpdated(DateUtil.currentGMTTime());
_jobDao.update(jobId, job);
txt.commit();
} catch(Exception e) {
s_logger.error("Unexpected exception while completing async job-" + jobId + " = [ " + jobUuid + " ]", e);
txt.rollback();
}
}
@Override @DB
public void updateAsyncJobStatus(long jobId, int processStatus, Object resultObject) {
AsyncJobVO job = _jobDao.findById(jobId);
String jobUuid = null;
if (job != null) {
jobUuid = job.getUuid();
if(s_logger.isDebugEnabled()) {
s_logger.debug("Update async-job progress, job-" + jobId + " = [ " + jobUuid + " ], processStatus: " + processStatus +
", result: " + resultObject);
}
} else {
if(s_logger.isDebugEnabled()) {
s_logger.debug("job-" + jobId + " no longer exists, we just log progress info here. progress status: " + processStatus);
}
return;
}
Transaction txt = Transaction.currentTxn();
try {
txt.start();
job.setProcessStatus(processStatus);
if(resultObject != null) {
job.setResult(ApiSerializerHelper.toSerializedStringOld(resultObject));
}
job.setLastUpdated(DateUtil.currentGMTTime());
_jobDao.update(jobId, job);
publishOnEventBus(job, "update");
txt.commit();
} catch(Exception e) {
s_logger.error("Unexpected exception while updating async job-" + jobId + " = [ " + jobUuid + " ] status: ", e);
txt.rollback();
}
}
@Override @DB
public void updateAsyncJobAttachment(long jobId, String instanceType, Long instanceId) {
AsyncJobVO job = _jobDao.findById(jobId);
String jobUuid = null;
if (job != null) {
jobUuid = job.getUuid();
if(s_logger.isDebugEnabled()) {
s_logger.debug("Update async-job attachment, job-" + jobId + " = [ " + jobUuid + " ], instanceType: "
+ instanceType + ", instanceId: " + instanceId);
}
} else {
if(s_logger.isDebugEnabled()) {
s_logger.debug("job-" + jobId + " no longer exists, instanceType: " + instanceType + ", instanceId: "
+ instanceId);
}
return;
}
Transaction txt = Transaction.currentTxn();
try {
txt.start();
//job.setInstanceType(instanceType);
job.setInstanceId(instanceId);
job.setLastUpdated(DateUtil.currentGMTTime());
_jobDao.update(jobId, job);
txt.commit();
} catch(Exception e) {
s_logger.error("Unexpected exception while updating async job-" + jobId + " = [ " + jobUuid + " ] attachment: ", e);
txt.rollback();
}
}
@Override
public void syncAsyncJobExecution(AsyncJob job, String syncObjType, long syncObjId, long queueSizeLimit) {
// This method is re-entrant. If an API developer wants to synchronized on an object, e.g. the router,
// when executing business logic, they will call this method (actually a method in BaseAsyncCmd that calls this).
// This method will get called every time their business logic executes. The first time it exectues for a job
// there will be no sync source, but on subsequent execution there will be a sync souce. If this is the first
// time the job executes we queue the job, otherwise we just return so that the business logic can execute.
if (job.getSyncSource() != null) {
return;
}
if(s_logger.isDebugEnabled()) {
s_logger.debug("Sync job-" + job.getId() + " = [ " + job.getUuid() + " ] execution on object " + syncObjType + "." + syncObjId);
}
SyncQueueVO queue = null;
// to deal with temporary DB exceptions like DB deadlock/Lock-wait time out cased rollbacks
// we retry five times until we throw an exception
Random random = new Random();
for(int i = 0; i < 5; i++) {
queue = _queueMgr.queue(syncObjType, syncObjId, SyncQueueItem.AsyncJobContentType, job.getId(), queueSizeLimit);
if(queue != null) {
break;
}
try {
Thread.sleep(1000 + random.nextInt(5000));
} catch (InterruptedException e) {
}
}
if (queue == null) {
throw new CloudRuntimeException("Unable to insert queue item into database, DB is full?");
} else {
throw new AsyncCommandQueued(queue, "job-" + job.getId() + " = [ " + job.getUuid() + " ] queued");
}
}
@Override
public AsyncJob queryAsyncJobResult(QueryAsyncJobResultCmd cmd) {
Account caller = CallContext.current().getCallingAccount();
AsyncJobVO job = _jobDao.findById(cmd.getId());
if (job == null) {
throw new InvalidParameterValueException("Unable to find a job by id " + cmd.getId());
}
User userJobOwner = _accountMgr.getUserIncludingRemoved(job.getUserId());
Account jobOwner = _accountMgr.getAccount(userJobOwner.getAccountId());
//check permissions
if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
//regular user can see only jobs he owns
if (caller.getId() != jobOwner.getId()) {
throw new PermissionDeniedException("Account " + caller + " is not authorized to see job-" + job.getId() + " = [ " + job.getUuid() + " ]");
}
} else if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
_accountMgr.checkAccess(caller, null, true, jobOwner);
}
//poll the job
queryAsyncJobResult(cmd.getId());
return _jobDao.findById(cmd.getId());
}
@Override @DB
public AsyncJobResult queryAsyncJobResult(long jobId) {
AsyncJobVO job = _jobDao.findById(jobId);
String jobUuid = null;
if (job != null) {
jobUuid = job.getUuid();
if(s_logger.isTraceEnabled()) {
s_logger.trace("Query async-job status, job-" + jobId + " = [ " + jobUuid + " ]");
}
} else {
if(s_logger.isDebugEnabled()) {
s_logger.debug("Async job-" + jobId + " does not exist, invalid job id?");
}
}
Transaction txt = Transaction.currentTxn();
AsyncJobResult jobResult = new AsyncJobResult(jobId);
try {
txt.start();
if(job != null) {
jobResult.setCmdOriginator(job.getCmdOriginator());
jobResult.setJobStatus(job.getStatus());
jobResult.setProcessStatus(job.getProcessStatus());
jobResult.setResult(job.getResult());
jobResult.setResultCode(job.getResultCode());
jobResult.setUuid(job.getUuid());
if(job.getStatus() == AsyncJobResult.STATUS_SUCCEEDED ||
job.getStatus() == AsyncJobResult.STATUS_FAILED) {
if(s_logger.isDebugEnabled()) {
s_logger.debug("Async job-" + jobId + " = [ " + jobUuid + " ] completed");
}
} else {
job.setLastPolled(DateUtil.currentGMTTime());
_jobDao.update(jobId, job);
}
} else {
jobResult.setJobStatus(AsyncJobResult.STATUS_FAILED);
jobResult.setResult("job-" + jobId + " does not exist");
}
txt.commit();
} catch(Exception e) {
if (jobUuid == null) {
s_logger.error("Unexpected exception while querying async job-" + jobId + " status: ", e);
} else {
s_logger.error("Unexpected exception while querying async job-" + jobId + " = [ " + jobUuid + " ] status: ", e);
}
jobResult.setJobStatus(AsyncJobResult.STATUS_FAILED);
jobResult.setResult("Exception: " + e.toString());
txt.rollback();
}
if(s_logger.isTraceEnabled()) {
s_logger.trace("Job status: " + jobResult.toString());
}
return jobResult;
}
private void scheduleExecution(final AsyncJobVO job) {
scheduleExecution(job, false);
}
private void scheduleExecution(final AsyncJobVO job, boolean executeInContext) {
Runnable runnable = getExecutorRunnable(this, job);
if (executeInContext) {
runnable.run();
} else {
_executor.submit(runnable);
}
}
private Runnable getExecutorRunnable(final AsyncJobManager mgr, final AsyncJobVO job) {
return new Runnable() {
@Override
public void run() {
try {
long jobId = 0;
try {
JmxUtil.registerMBean("AsyncJobManager", "Active Job " + job.getId(), new AsyncJobMBeanImpl(job));
} catch(Exception e) {
s_logger.warn("Unable to register active job [ " + job.getId() + " ] = [ " + job.getUuid() + " ] to JMX monitoring due to exception " + ExceptionUtil.toString(e));
}
BaseAsyncCmd cmdObj = null;
Transaction txn = Transaction.open(Transaction.CLOUD_DB);
try {
jobId = job.getId();
String jobUuid = job.getUuid();
NDC.push("job-" + jobId + " = [ " + jobUuid + " ]");
if(s_logger.isDebugEnabled()) {
s_logger.debug("Executing " + job.getCmd() + " for job-" + jobId + " = [ " + jobUuid + " ]");
}
Class<?> cmdClass = Class.forName(job.getCmd());
cmdObj = (BaseAsyncCmd)cmdClass.newInstance();
cmdObj = ComponentContext.inject(cmdObj);
cmdObj.configure();
cmdObj.setJob(job);
Type mapType = new TypeToken<Map<String, String>>() {}.getType();
Gson gson = ApiGsonHelper.getBuilder().create();
Map<String, String> params = gson.fromJson(job.getCmdInfo(), mapType);
// whenever we deserialize, the UserContext needs to be updated
String userIdStr = params.get("ctxUserId");
String acctIdStr = params.get("ctxAccountId");
Long userId = null;
Account accountObject = null;
User user = null;
if (userIdStr != null) {
userId = Long.parseLong(userIdStr);
user = _entityMgr.findById(User.class, userId);
}
if (acctIdStr != null) {
accountObject = _accountDao.findById(Long.parseLong(acctIdStr));
}
CallContext.register(user, accountObject);
try {
// dispatch could ultimately queue the job
_dispatcher.dispatch(cmdObj, params);
// serialize this to the async job table
completeAsyncJob(jobId, AsyncJobResult.STATUS_SUCCEEDED, 0, cmdObj.getResponseObject());
} finally {
CallContext.unregister();
}
// commands might need to be queued as part of synchronization here, so they just have to be re-dispatched from the queue mechanism...
if (job.getSyncSource() != null) {
_queueMgr.purgeItem(job.getSyncSource().getId());
checkQueue(job.getSyncSource().getQueueId());
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Done executing " + job.getCmd() + " for job-" + job.getId() + " = [ " + jobUuid + " ]");
}
} catch(Throwable e) {
if (e instanceof AsyncCommandQueued) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("job " + job.getCmd() + " for job-" + jobId + " = [ " + job.getUuid() + " ] was queued, processing the queue.");
}
checkQueue(((AsyncCommandQueued)e).getQueue().getId());
} else {
String errorMsg = null;
int errorCode = ApiErrorCode.INTERNAL_ERROR.getHttpCode();
if (!(e instanceof ServerApiException)) {
s_logger.error("Unexpected exception while executing " + job.getCmd(), e);
errorMsg = e.getMessage();
} else {
ServerApiException sApiEx = (ServerApiException)e;
errorMsg = sApiEx.getDescription();
errorCode = sApiEx.getErrorCode().getHttpCode();
}
ExceptionResponse response = new ExceptionResponse();
response.setErrorCode(errorCode);
response.setErrorText(errorMsg);
response.setResponseName((cmdObj == null) ? "unknowncommandresponse" : cmdObj.getCommandName());
// FIXME: setting resultCode to ApiErrorCode.INTERNAL_ERROR is not right, usually executors have their exception handling
// and we need to preserve that as much as possible here
completeAsyncJob(jobId, AsyncJobResult.STATUS_FAILED, ApiErrorCode.INTERNAL_ERROR.getHttpCode(), response);
// need to clean up any queue that happened as part of the dispatching and move on to the next item in the queue
try {
if (job.getSyncSource() != null) {
_queueMgr.purgeItem(job.getSyncSource().getId());
checkQueue(job.getSyncSource().getQueueId());
}
} catch(Throwable ex) {
s_logger.fatal("Exception on exception, log it for record", ex);
}
}
} finally {
try {
JmxUtil.unregisterMBean("AsyncJobManager", "Active Job " + job.getId());
} catch(Exception e) {
s_logger.warn("Unable to unregister active job [ " + job.getId() + " ] = [ " + job.getUuid() + " ] from JMX monitoring");
}
txn.close();
NDC.pop();
}
} catch (Throwable th) {
try {
s_logger.error("Caught: " + th);
} catch (Throwable th2) {
}
}
}
};
}
private void executeQueueItem(SyncQueueItemVO item, boolean fromPreviousSession) {
long jobId = item.getContentId();
AsyncJobVO job = _jobDao.findById(item.getContentId());
if (job != null) {
String jobUuid = job.getUuid();
if(s_logger.isDebugEnabled()) {
s_logger.debug("Schedule queued job-" + jobId + " = [ " + jobUuid + " ]");
}
job.setFromPreviousSession(fromPreviousSession);
job.setSyncSource(item);
job.setCompleteMsid(getMsid());
_jobDao.update(job.getId(), job);
try {
scheduleExecution(job);
} catch(RejectedExecutionException e) {
s_logger.warn("Execution for job-" + jobId + " = [ " + jobUuid + " ] is rejected, return it to the queue for next turn");
_queueMgr.returnItem(item.getId());
}
} else {
if(s_logger.isDebugEnabled()) {
s_logger.debug("Unable to find related job for queue item: " + item.toString());
}
_queueMgr.purgeItem(item.getId());
}
}
@Override
public void releaseSyncSource(AsyncJobExecutor executor) {
if(executor.getSyncSource() != null) {
if(s_logger.isDebugEnabled()) {
s_logger.debug("Release sync source for job-" + executor.getJob().getId() + " = [ " + executor.getJob().getUuid() + " ] sync source: "
+ executor.getSyncSource().getContentType() + "-"
+ executor.getSyncSource().getContentId());
}
_queueMgr.purgeItem(executor.getSyncSource().getId());
checkQueue(executor.getSyncSource().getQueueId());
}
}
private void checkQueue(long queueId) {
while(true) {
try {
SyncQueueItemVO item = _queueMgr.dequeueFromOne(queueId, getMsid());
if(item != null) {
if(s_logger.isDebugEnabled()) {
s_logger.debug("Executing sync queue item: " + item.toString());
}
executeQueueItem(item, false);
} else {
break;
}
} catch(Throwable e) {
s_logger.error("Unexpected exception when kicking sync queue-" + queueId, e);
break;
}
}
}
private Runnable getHeartbeatTask() {
return new Runnable() {
@Override
public void run() {
try {
List<SyncQueueItemVO> l = _queueMgr.dequeueFromAny(getMsid(), MAX_ONETIME_SCHEDULE_SIZE);
if(l != null && l.size() > 0) {
for(SyncQueueItemVO item: l) {
if(s_logger.isDebugEnabled()) {
s_logger.debug("Execute sync-queue item: " + item.toString());
}
executeQueueItem(item, false);
}
}
} catch(Throwable e) {
s_logger.error("Unexpected exception when trying to execute queue item, ", e);
}
}
};
}
@DB
private Runnable getGCTask() {
return new Runnable() {
@Override
public void run() {
GlobalLock scanLock = GlobalLock.getInternLock("AsyncJobManagerGC");
try {
if(scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
try {
reallyRun();
} finally {
scanLock.unlock();
}
}
} finally {
scanLock.releaseRef();
}
}
public void reallyRun() {
try {
s_logger.trace("Begin cleanup expired async-jobs");
Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - _jobExpireSeconds*1000);
// limit to 100 jobs per turn, this gives cleanup throughput as 600 jobs per minute
// hopefully this will be fast enough to balance potential growth of job table
//1) Expire unfinished jobs that weren't processed yet
List<AsyncJobVO> l = _jobDao.getExpiredUnfinishedJobs(cutTime, 100);
for(AsyncJobVO job : l) {
s_logger.trace("Expunging unfinished job " + job);
expungeAsyncJob(job);
}
//2) Expunge finished jobs
List<AsyncJobVO> completedJobs = _jobDao.getExpiredCompletedJobs(cutTime, 100);
for(AsyncJobVO job : completedJobs) {
s_logger.trace("Expunging completed job " + job);
expungeAsyncJob(job);
}
// forcefully cancel blocking queue items if they've been staying there for too long
List<SyncQueueItemVO> blockItems = _queueMgr.getBlockedQueueItems(_jobCancelThresholdSeconds*1000, false);
if(blockItems != null && blockItems.size() > 0) {
for(SyncQueueItemVO item : blockItems) {
if(item.getContentType().equalsIgnoreCase(SyncQueueItem.AsyncJobContentType)) {
completeAsyncJob(item.getContentId(), AsyncJobResult.STATUS_FAILED, 0,
getResetResultResponse("Job is cancelled as it has been blocking others for too long"));
}
// purge the item and resume queue processing
_queueMgr.purgeItem(item.getId());
}
}
s_logger.trace("End cleanup expired async-jobs");
} catch(Throwable e) {
s_logger.error("Unexpected exception when trying to execute queue item, ", e);
}
}
};
}
@DB
protected void expungeAsyncJob(AsyncJobVO job) {
Transaction txn = Transaction.currentTxn();
txn.start();
_jobDao.expunge(job.getId());
//purge corresponding sync queue item
_queueMgr.purgeAsyncJobQueueItemId(job.getId());
txn.commit();
}
private long getMsid() {
return ManagementServerNode.getManagementServerId();
}
private void cleanupPendingJobs(List<SyncQueueItemVO> l) {
if(l != null && l.size() > 0) {
for(SyncQueueItemVO item: l) {
if(s_logger.isInfoEnabled()) {
s_logger.info("Discard left-over queue item: " + item.toString());
}
String contentType = item.getContentType();
if(contentType != null && contentType.equalsIgnoreCase(SyncQueueItem.AsyncJobContentType)) {
Long jobId = item.getContentId();
if(jobId != null) {
s_logger.warn("Mark job as failed as its correspoding queue-item has been discarded. job id: " + jobId);
completeAsyncJob(jobId, AsyncJobResult.STATUS_FAILED, 0, getResetResultResponse("Execution was cancelled because of server shutdown"));
}
}
_queueMgr.purgeItem(item.getId());
}
}
}
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
int expireMinutes = NumbersUtil.parseInt(
_configDao.getValue(Config.JobExpireMinutes.key()), 24*60);
_jobExpireSeconds = (long)expireMinutes*60;
_jobCancelThresholdSeconds = NumbersUtil.parseInt(
_configDao.getValue(Config.JobCancelThresholdMinutes.key()), 60);
_jobCancelThresholdSeconds *= 60;
try {
final File dbPropsFile = PropertiesUtil.findConfigFile("db.properties");
final Properties dbProps = new Properties();
dbProps.load(new FileInputStream(dbPropsFile));
final int cloudMaxActive = Integer.parseInt(dbProps.getProperty("db.cloud.maxActive"));
int poolSize = (cloudMaxActive * 2) / 3;
s_logger.info("Start AsyncJobManager thread pool in size " + poolSize);
_executor = Executors.newFixedThreadPool(poolSize, new NamedThreadFactory("Job-Executor"));
} catch (final Exception e) {
throw new ConfigurationException("Unable to load db.properties to configure AsyncJobManagerImpl");
}
return true;
}
@Override
public void onManagementNodeJoined(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
}
@Override
public void onManagementNodeLeft(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
for (ManagementServerHost msHost : nodeList) {
Transaction txn = Transaction.open(Transaction.CLOUD_DB);
try {
txn.start();
List<SyncQueueItemVO> items = _queueMgr.getActiveQueueItems(msHost.getId(), true);
cleanupPendingJobs(items);
_jobDao.resetJobProcess(msHost.getId(), ApiErrorCode.INTERNAL_ERROR.getHttpCode(), getSerializedErrorMessage("job cancelled because of management server restart"));
txn.commit();
} catch(Throwable e) {
s_logger.warn("Unexpected exception ", e);
txn.rollback();
} finally {
txn.close();
}
}
}
@Override
public void onManagementNodeIsolated() {
}
@Override
public boolean start() {
try {
List<SyncQueueItemVO> l = _queueMgr.getActiveQueueItems(getMsid(), false);
cleanupPendingJobs(l);
_jobDao.resetJobProcess(getMsid(), ApiErrorCode.INTERNAL_ERROR.getHttpCode(), getSerializedErrorMessage("job cancelled because of management server restart"));
} catch(Throwable e) {
s_logger.error("Unexpected exception " + e.getMessage(), e);
}
_heartbeatScheduler.scheduleAtFixedRate(getHeartbeatTask(), HEARTBEAT_INTERVAL,
HEARTBEAT_INTERVAL, TimeUnit.MILLISECONDS);
_heartbeatScheduler.scheduleAtFixedRate(getGCTask(), GC_INTERVAL,
GC_INTERVAL, TimeUnit.MILLISECONDS);
return true;
}
private static ExceptionResponse getResetResultResponse(String errorMessage) {
ExceptionResponse resultObject = new ExceptionResponse();
resultObject.setErrorCode(ApiErrorCode.INTERNAL_ERROR.getHttpCode());
resultObject.setErrorText(errorMessage);
return resultObject;
}
private static String getSerializedErrorMessage(String errorMessage) {
return ApiSerializerHelper.toSerializedStringOld(getResetResultResponse(errorMessage));
}
@Override
public boolean stop() {
_heartbeatScheduler.shutdown();
_executor.shutdown();
return true;
}
}

View File

@ -16,16 +16,14 @@
// under the License. // under the License.
package com.cloud.async; package com.cloud.async;
import org.apache.cloudstack.jobs.JobInfo;
import com.cloud.api.ApiSerializerHelper; import com.cloud.api.ApiSerializerHelper;
public class AsyncJobResult { public class AsyncJobResult {
public static final int STATUS_IN_PROGRESS = 0;
public static final int STATUS_SUCCEEDED = 1;
public static final int STATUS_FAILED = 2;
private String cmdOriginator;
private long jobId; private long jobId;
private int jobStatus; private JobInfo.Status jobStatus;
private int processStatus; private int processStatus;
private int resultCode; private int resultCode;
private String result; private String result;
@ -33,20 +31,12 @@ public class AsyncJobResult {
public AsyncJobResult(long jobId) { public AsyncJobResult(long jobId) {
this.jobId = jobId; this.jobId = jobId;
jobStatus = STATUS_IN_PROGRESS; jobStatus = JobInfo.Status.IN_PROGRESS;
processStatus = 0; processStatus = 0;
resultCode = 0; resultCode = 0;
result = ""; result = "";
} }
public String getCmdOriginator() {
return cmdOriginator;
}
public void setCmdOriginator(String cmdOriginator) {
this.cmdOriginator = cmdOriginator;
}
public long getJobId() { public long getJobId() {
return jobId; return jobId;
} }
@ -56,18 +46,18 @@ public class AsyncJobResult {
} }
public String getUuid() { public String getUuid() {
return this.uuid; return uuid;
} }
public void setUuid(String uuid) { public void setUuid(String uuid) {
this.uuid = uuid; this.uuid = uuid;
} }
public int getJobStatus() { public JobInfo.Status getJobStatus() {
return jobStatus; return jobStatus;
} }
public void setJobStatus(int jobStatus) { public void setJobStatus(JobInfo.Status jobStatus) {
this.jobStatus = jobStatus; this.jobStatus = jobStatus;
} }
@ -100,14 +90,14 @@ public class AsyncJobResult {
} }
public void setResultObject(Object result) { public void setResultObject(Object result) {
this.result = ApiSerializerHelper.toSerializedStringOld(result); this.result = ApiSerializerHelper.toSerializedString(result);
} }
@Override @Override
public String toString() { public String toString() {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
sb.append("AsyncJobResult {jobId:").append(getJobId()); sb.append("AsyncJobResult {jobId:").append(getJobId());
sb.append(", jobStatus: ").append(getJobStatus()); sb.append(", jobStatus: ").append(getJobStatus().ordinal());
sb.append(", processStatus: ").append(getProcessStatus()); sb.append(", processStatus: ").append(getProcessStatus());
sb.append(", resultCode: ").append(getResultCode()); sb.append(", resultCode: ").append(getResultCode());
sb.append(", result: ").append(result); sb.append(", result: ").append(result);

View File

@ -1,403 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async;
import java.util.Date;
import java.util.UUID;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import com.cloud.utils.db.GenericDao;
import org.apache.cloudstack.api.ApiCommandJobType;
import org.apache.cloudstack.api.InternalIdentity;
@Entity
@Table(name="async_job")
public class AsyncJobVO implements AsyncJob {
public static final int CALLBACK_POLLING = 0;
public static final int CALLBACK_EMAIL = 1;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private Long id = null;
@Column(name="user_id")
private long userId;
@Column(name="account_id")
private long accountId;
@Column(name="session_key")
private String sessionKey;
@Column(name="job_cmd")
private String cmd;
@Column(name="job_cmd_originator")
private String cmdOriginator;
@Column(name="job_cmd_ver")
private int cmdVersion;
@Column(name="job_cmd_info", length=65535)
private String cmdInfo;
@Column(name="callback_type")
private int callbackType;
@Column(name="callback_address")
private String callbackAddress;
@Column(name="job_status")
private int status;
@Column(name="job_process_status")
private int processStatus;
@Column(name="job_result_code")
private int resultCode;
@Column(name="job_result", length=65535)
private String result;
@Enumerated(value=EnumType.STRING)
@Column(name="instance_type", length=64)
private ApiCommandJobType instanceType;
@Column(name="instance_id", length=64)
private Long instanceId;
@Column(name="job_init_msid")
private Long initMsid;
@Column(name="job_complete_msid")
private Long completeMsid;
@Column(name=GenericDao.CREATED_COLUMN)
private Date created;
@Column(name="last_updated")
@Temporal(TemporalType.TIMESTAMP)
private Date lastUpdated;
@Column(name="last_polled")
@Temporal(TemporalType.TIMESTAMP)
private Date lastPolled;
@Column(name=GenericDao.REMOVED_COLUMN)
private Date removed;
@Column(name="uuid")
private String uuid;
@Transient
private SyncQueueItemVO syncSource = null;
@Transient
private boolean fromPreviousSession = false;
public AsyncJobVO() {
this.uuid = UUID.randomUUID().toString();
}
public AsyncJobVO(long userId, long accountId, String cmd, String cmdInfo, Long instanceId, ApiCommandJobType instanceType) {
this.userId = userId;
this.accountId = accountId;
this.cmd = cmd;
this.cmdInfo = cmdInfo;
this.callbackType = CALLBACK_POLLING;
this.uuid = UUID.randomUUID().toString();
this.instanceId = instanceId;
this.instanceType = instanceType;
}
public AsyncJobVO(long userId, long accountId, String cmd, String cmdInfo,
int callbackType, String callbackAddress, Long instanceId, ApiCommandJobType instanceType) {
this(userId, accountId, cmd, cmdInfo, instanceId, instanceType);
this.callbackType = callbackType;
this.callbackAddress = callbackAddress;
this.uuid = UUID.randomUUID().toString();
}
@Override
public long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Override
public long getUserId() {
return userId;
}
public void setUserId(long userId) {
this.userId = userId;
}
@Override
public long getAccountId() {
return accountId;
}
public void setAccountId(long accountId) {
this.accountId = accountId;
}
@Override
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
@Override
public int getCmdVersion() {
return cmdVersion;
}
public void setCmdVersion(int version) {
cmdVersion = version;
}
@Override
public String getCmdInfo() {
return cmdInfo;
}
public void setCmdInfo(String cmdInfo) {
this.cmdInfo = cmdInfo;
}
@Override
public int getCallbackType() {
return callbackType;
}
public void setCallbackType(int callbackType) {
this.callbackType = callbackType;
}
@Override
public String getCallbackAddress() {
return callbackAddress;
}
public void setCallbackAddress(String callbackAddress) {
this.callbackAddress = callbackAddress;
}
@Override
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
@Override
public int getProcessStatus() {
return processStatus;
}
public void setProcessStatus(int status) {
processStatus = status;
}
@Override
public int getResultCode() {
return resultCode;
}
public void setResultCode(int resultCode) {
this.resultCode = resultCode;
}
@Override
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
@Override
public Long getInitMsid() {
return initMsid;
}
public void setInitMsid(Long initMsid) {
this.initMsid = initMsid;
}
@Override
public Long getCompleteMsid() {
return completeMsid;
}
public void setCompleteMsid(Long completeMsid) {
this.completeMsid = completeMsid;
}
@Override
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
@Override
public Date getLastUpdated() {
return lastUpdated;
}
public void setLastUpdated(Date lastUpdated) {
this.lastUpdated = lastUpdated;
}
@Override
public Date getLastPolled() {
return lastPolled;
}
public void setLastPolled(Date lastPolled) {
this.lastPolled = lastPolled;
}
@Override
public Date getRemoved() {
return removed;
}
public void setRemoved(Date removed) {
this.removed = removed;
}
@Override
public ApiCommandJobType getInstanceType() {
return instanceType;
}
public void setInstanceType(ApiCommandJobType instanceType) {
this.instanceType = instanceType;
}
@Override
public Long getInstanceId() {
return instanceId;
}
public void setInstanceId(Long instanceId) {
this.instanceId = instanceId;
}
@Override
public String getSessionKey() {
return sessionKey;
}
public void setSessionKey(String sessionKey) {
this.sessionKey = sessionKey;
}
@Override
public String getCmdOriginator() {
return cmdOriginator;
}
public void setCmdOriginator(String cmdOriginator) {
this.cmdOriginator = cmdOriginator;
}
@Override
public SyncQueueItemVO getSyncSource() {
return syncSource;
}
public void setSyncSource(SyncQueueItemVO syncSource) {
this.syncSource = syncSource;
}
@Override
public boolean isFromPreviousSession() {
return fromPreviousSession;
}
public void setFromPreviousSession(boolean fromPreviousSession) {
this.fromPreviousSession = fromPreviousSession;
}
@Override
public String getUuid() {
return this.uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("AsyncJobVO {id:").append(getId());
sb.append(", userId: ").append(getUserId());
sb.append(", accountId: ").append(getAccountId());
sb.append(", sessionKey: ").append(getSessionKey());
sb.append(", instanceType: ").append(getInstanceType());
sb.append(", instanceId: ").append(getInstanceId());
sb.append(", cmd: ").append(getCmd());
sb.append(", cmdOriginator: ").append(getCmdOriginator());
sb.append(", cmdInfo: ").append(getCmdInfo());
sb.append(", cmdVersion: ").append(getCmdVersion());
sb.append(", callbackType: ").append(getCallbackType());
sb.append(", callbackAddress: ").append(getCallbackAddress());
sb.append(", status: ").append(getStatus());
sb.append(", processStatus: ").append(getProcessStatus());
sb.append(", resultCode: ").append(getResultCode());
sb.append(", result: ").append(getResult());
sb.append(", initMsid: ").append(getInitMsid());
sb.append(", completeMsid: ").append(getCompleteMsid());
sb.append(", lastUpdated: ").append(getLastUpdated());
sb.append(", lastPolled: ").append(getLastPolled());
sb.append(", created: ").append(getCreated());
sb.append("}");
return sb.toString();
}
}

View File

@ -1,69 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async;
public abstract class BaseAsyncJobExecutor implements AsyncJobExecutor {
private SyncQueueItemVO _syncSource;
private AsyncJobVO _job;
private boolean _fromPreviousSession;
private AsyncJobManager _asyncJobMgr;
private static ThreadLocal<AsyncJobExecutor> s_currentExector = new ThreadLocal<AsyncJobExecutor>();
public AsyncJobManager getAsyncJobMgr() {
return _asyncJobMgr;
}
public void setAsyncJobMgr(AsyncJobManager asyncMgr) {
_asyncJobMgr = asyncMgr;
}
public SyncQueueItemVO getSyncSource() {
return _syncSource;
}
public void setSyncSource(SyncQueueItemVO syncSource) {
_syncSource = syncSource;
}
public AsyncJobVO getJob() {
return _job;
}
public void setJob(AsyncJobVO job) {
_job = job;
}
public void setFromPreviousSession(boolean value) {
_fromPreviousSession = value;
}
public boolean isFromPreviousSession() {
return _fromPreviousSession;
}
public abstract boolean execute();
public static AsyncJobExecutor getCurrentExecutor() {
return s_currentExector.get();
}
public static void setCurrentExecutor(AsyncJobExecutor currentExecutor) {
s_currentExector.set(currentExecutor);
}
}

View File

@ -1,141 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async;
import org.apache.cloudstack.api.InternalIdentity;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@Table(name="sync_queue_item")
public class SyncQueueItemVO implements SyncQueueItem, InternalIdentity {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private Long id = null;
@Column(name="queue_id")
private Long queueId;
@Column(name="content_type")
private String contentType;
@Column(name="content_id")
private Long contentId;
@Column(name="queue_proc_msid")
private Long lastProcessMsid;
@Column(name="queue_proc_number")
private Long lastProcessNumber;
@Column(name="queue_proc_time")
@Temporal(TemporalType.TIMESTAMP)
private Date lastProcessTime;
@Column(name="created")
private Date created;
public long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getQueueId() {
return queueId;
}
public void setQueueId(Long queueId) {
this.queueId = queueId;
}
@Override
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
@Override
public Long getContentId() {
return contentId;
}
public void setContentId(Long contentId) {
this.contentId = contentId;
}
public Long getLastProcessMsid() {
return lastProcessMsid;
}
public void setLastProcessMsid(Long lastProcessMsid) {
this.lastProcessMsid = lastProcessMsid;
}
public Long getLastProcessNumber() {
return lastProcessNumber;
}
public void setLastProcessNumber(Long lastProcessNumber) {
this.lastProcessNumber = lastProcessNumber;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("SyncQueueItemVO {id:").append(getId()).append(", queueId: ").append(getQueueId());
sb.append(", contentType: ").append(getContentType());
sb.append(", contentId: ").append(getContentId());
sb.append(", lastProcessMsid: ").append(getLastProcessMsid());
sb.append(", lastprocessNumber: ").append(getLastProcessNumber());
sb.append(", lastProcessTime: ").append(getLastProcessTime());
sb.append(", created: ").append(getCreated());
sb.append("}");
return sb.toString();
}
public Date getLastProcessTime() {
return lastProcessTime;
}
public void setLastProcessTime(Date lastProcessTime) {
this.lastProcessTime = lastProcessTime;
}
}

View File

@ -1,35 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async;
import java.util.List;
import com.cloud.utils.component.Manager;
public interface SyncQueueManager extends Manager {
public SyncQueueVO queue(String syncObjType, long syncObjId, String itemType, long itemId, long queueSizeLimit);
public SyncQueueItemVO dequeueFromOne(long queueId, Long msid);
public List<SyncQueueItemVO> dequeueFromAny(Long msid, int maxItems);
public void purgeItem(long queueItemId);
public void returnItem(long queueItemId);
public List<SyncQueueItemVO> getActiveQueueItems(Long msid, boolean exclusive);
public List<SyncQueueItemVO> getBlockedQueueItems(long thresholdMs, boolean exclusive);
void purgeAsyncJobQueueItemId(long asyncJobId);
}

View File

@ -1,253 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.async.dao.SyncQueueDao;
import com.cloud.async.dao.SyncQueueItemDao;
import com.cloud.utils.DateUtil;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
@Component
@Local(value={SyncQueueManager.class})
public class SyncQueueManagerImpl extends ManagerBase implements SyncQueueManager {
public static final Logger s_logger = Logger.getLogger(SyncQueueManagerImpl.class.getName());
@Inject private SyncQueueDao _syncQueueDao;
@Inject private SyncQueueItemDao _syncQueueItemDao;
@Override
@DB
public SyncQueueVO queue(String syncObjType, long syncObjId, String itemType, long itemId, long queueSizeLimit) {
Transaction txn = Transaction.currentTxn();
try {
txn.start();
_syncQueueDao.ensureQueue(syncObjType, syncObjId);
SyncQueueVO queueVO = _syncQueueDao.find(syncObjType, syncObjId);
if(queueVO == null)
throw new CloudRuntimeException("Unable to queue item into DB, DB is full?");
queueVO.setQueueSizeLimit(queueSizeLimit);
_syncQueueDao.update(queueVO.getId(), queueVO);
Date dt = DateUtil.currentGMTTime();
SyncQueueItemVO item = new SyncQueueItemVO();
item.setQueueId(queueVO.getId());
item.setContentType(itemType);
item.setContentId(itemId);
item.setCreated(dt);
_syncQueueItemDao.persist(item);
txn.commit();
return queueVO;
} catch(Exception e) {
s_logger.error("Unexpected exception: ", e);
txn.rollback();
}
return null;
}
@Override
@DB
public SyncQueueItemVO dequeueFromOne(long queueId, Long msid) {
Transaction txt = Transaction.currentTxn();
try {
txt.start();
SyncQueueVO queueVO = _syncQueueDao.lockRow(queueId, true);
if(queueVO == null) {
s_logger.error("Sync queue(id: " + queueId + ") does not exist");
txt.commit();
return null;
}
if(queueReadyToProcess(queueVO)) {
SyncQueueItemVO itemVO = _syncQueueItemDao.getNextQueueItem(queueVO.getId());
if(itemVO != null) {
Long processNumber = queueVO.getLastProcessNumber();
if(processNumber == null)
processNumber = new Long(1);
else
processNumber = processNumber + 1;
Date dt = DateUtil.currentGMTTime();
queueVO.setLastProcessNumber(processNumber);
queueVO.setLastUpdated(dt);
queueVO.setQueueSize(queueVO.getQueueSize() + 1);
_syncQueueDao.update(queueVO.getId(), queueVO);
itemVO.setLastProcessMsid(msid);
itemVO.setLastProcessNumber(processNumber);
itemVO.setLastProcessTime(dt);
_syncQueueItemDao.update(itemVO.getId(), itemVO);
txt.commit();
return itemVO;
} else {
if(s_logger.isDebugEnabled())
s_logger.debug("Sync queue (" + queueId + ") is currently empty");
}
} else {
if(s_logger.isDebugEnabled())
s_logger.debug("There is a pending process in sync queue(id: " + queueId + ")");
}
txt.commit();
} catch(Exception e) {
s_logger.error("Unexpected exception: ", e);
txt.rollback();
}
return null;
}
@Override
@DB
public List<SyncQueueItemVO> dequeueFromAny(Long msid, int maxItems) {
List<SyncQueueItemVO> resultList = new ArrayList<SyncQueueItemVO>();
Transaction txt = Transaction.currentTxn();
try {
txt.start();
List<SyncQueueItemVO> l = _syncQueueItemDao.getNextQueueItems(maxItems);
if(l != null && l.size() > 0) {
for(SyncQueueItemVO item : l) {
SyncQueueVO queueVO = _syncQueueDao.lockRow(item.getQueueId(), true);
SyncQueueItemVO itemVO = _syncQueueItemDao.lockRow(item.getId(), true);
if(queueReadyToProcess(queueVO) && itemVO.getLastProcessNumber() == null) {
Long processNumber = queueVO.getLastProcessNumber();
if(processNumber == null)
processNumber = new Long(1);
else
processNumber = processNumber + 1;
Date dt = DateUtil.currentGMTTime();
queueVO.setLastProcessNumber(processNumber);
queueVO.setLastUpdated(dt);
queueVO.setQueueSize(queueVO.getQueueSize() + 1);
_syncQueueDao.update(queueVO.getId(), queueVO);
itemVO.setLastProcessMsid(msid);
itemVO.setLastProcessNumber(processNumber);
itemVO.setLastProcessTime(dt);
_syncQueueItemDao.update(item.getId(), itemVO);
resultList.add(item);
}
}
}
txt.commit();
return resultList;
} catch(Exception e) {
s_logger.error("Unexpected exception: ", e);
txt.rollback();
}
return null;
}
@Override
@DB
public void purgeItem(long queueItemId) {
Transaction txt = Transaction.currentTxn();
try {
txt.start();
SyncQueueItemVO itemVO = _syncQueueItemDao.findById(queueItemId);
if(itemVO != null) {
SyncQueueVO queueVO = _syncQueueDao.lockRow(itemVO.getQueueId(), true);
_syncQueueItemDao.expunge(itemVO.getId());
//if item is active, reset queue information
if (itemVO.getLastProcessMsid() != null) {
queueVO.setLastUpdated(DateUtil.currentGMTTime());
//decrement the count
assert (queueVO.getQueueSize() > 0) : "Count reduce happens when it's already <= 0!";
queueVO.setQueueSize(queueVO.getQueueSize() - 1);
_syncQueueDao.update(queueVO.getId(), queueVO);
}
}
txt.commit();
} catch(Exception e) {
s_logger.error("Unexpected exception: ", e);
txt.rollback();
}
}
@Override
@DB
public void returnItem(long queueItemId) {
Transaction txt = Transaction.currentTxn();
try {
txt.start();
SyncQueueItemVO itemVO = _syncQueueItemDao.findById(queueItemId);
if(itemVO != null) {
SyncQueueVO queueVO = _syncQueueDao.lockRow(itemVO.getQueueId(), true);
itemVO.setLastProcessMsid(null);
itemVO.setLastProcessNumber(null);
itemVO.setLastProcessTime(null);
_syncQueueItemDao.update(queueItemId, itemVO);
queueVO.setLastUpdated(DateUtil.currentGMTTime());
_syncQueueDao.update(queueVO.getId(), queueVO);
}
txt.commit();
} catch(Exception e) {
s_logger.error("Unexpected exception: ", e);
txt.rollback();
}
}
@Override
public List<SyncQueueItemVO> getActiveQueueItems(Long msid, boolean exclusive) {
return _syncQueueItemDao.getActiveQueueItems(msid, exclusive);
}
@Override
public List<SyncQueueItemVO> getBlockedQueueItems(long thresholdMs, boolean exclusive) {
return _syncQueueItemDao.getBlockedQueueItems(thresholdMs, exclusive);
}
private boolean queueReadyToProcess(SyncQueueVO queueVO) {
return queueVO.getQueueSize() < queueVO.getQueueSizeLimit();
}
@Override
public void purgeAsyncJobQueueItemId(long asyncJobId) {
Long itemId = _syncQueueItemDao.getQueueItemIdByContentIdAndType(asyncJobId, SyncQueueItem.AsyncJobContentType);
if (itemId != null) {
purgeItem(itemId);
}
}
}

View File

@ -1,137 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async;
import org.apache.cloudstack.api.InternalIdentity;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@Table(name="sync_queue")
public class SyncQueueVO implements InternalIdentity {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private Long id;
@Column(name="sync_objtype")
private String syncObjType;
@Column(name="sync_objid")
private Long syncObjId;
@Column(name="queue_proc_number")
private Long lastProcessNumber;
@Column(name="created")
@Temporal(TemporalType.TIMESTAMP)
private Date created;
@Column(name="last_updated")
@Temporal(TemporalType.TIMESTAMP)
private Date lastUpdated;
@Column(name="queue_size")
private long queueSize = 0;
@Column(name="queue_size_limit")
private long queueSizeLimit = 0;
public long getId() {
return id;
}
public String getSyncObjType() {
return syncObjType;
}
public void setSyncObjType(String syncObjType) {
this.syncObjType = syncObjType;
}
public Long getSyncObjId() {
return syncObjId;
}
public void setSyncObjId(Long syncObjId) {
this.syncObjId = syncObjId;
}
public Long getLastProcessNumber() {
return lastProcessNumber;
}
public void setLastProcessNumber(Long number) {
lastProcessNumber = number;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getLastUpdated() {
return lastUpdated;
}
public void setLastUpdated(Date lastUpdated) {
this.lastUpdated = lastUpdated;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("SyncQueueVO {id:").append(getId());
sb.append(", syncObjType: ").append(getSyncObjType());
sb.append(", syncObjId: ").append(getSyncObjId());
sb.append(", lastProcessNumber: ").append(getLastProcessNumber());
sb.append(", lastUpdated: ").append(getLastUpdated());
sb.append(", created: ").append(getCreated());
sb.append(", count: ").append(getQueueSize());
sb.append("}");
return sb.toString();
}
public long getQueueSize() {
return queueSize;
}
public void setQueueSize(long queueSize) {
this.queueSize = queueSize;
}
public long getQueueSizeLimit() {
return queueSizeLimit;
}
public void setQueueSizeLimit(long queueSizeLimit) {
this.queueSizeLimit = queueSizeLimit;
}
}

View File

@ -1,33 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async.dao;
import java.util.Date;
import java.util.List;
import org.apache.cloudstack.api.ApiCommandJobType;
import com.cloud.async.AsyncJobVO;
import com.cloud.utils.db.GenericDao;
public interface AsyncJobDao extends GenericDao<AsyncJobVO, Long> {
AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId);
List<AsyncJobVO> findInstancePendingAsyncJobs(ApiCommandJobType instanceType, Long accountId);
List<AsyncJobVO> getExpiredUnfinishedJobs(Date cutTime, int limit);
void resetJobProcess(long msid, int jobResultCode, String jobResultMessage);
List<AsyncJobVO> getExpiredCompletedJobs(Date cutTime, int limit);
}

View File

@ -1,150 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async.dao;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import javax.ejb.Local;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.api.ApiCommandJobType;
import com.cloud.async.AsyncJobResult;
import com.cloud.async.AsyncJobVO;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
@Component
@Local(value = { AsyncJobDao.class })
public class AsyncJobDaoImpl extends GenericDaoBase<AsyncJobVO, Long> implements AsyncJobDao {
private static final Logger s_logger = Logger.getLogger(AsyncJobDaoImpl.class.getName());
private final SearchBuilder<AsyncJobVO> pendingAsyncJobSearch;
private final SearchBuilder<AsyncJobVO> pendingAsyncJobsSearch;
private final SearchBuilder<AsyncJobVO> expiringUnfinishedAsyncJobSearch;
private final SearchBuilder<AsyncJobVO> expiringCompletedAsyncJobSearch;
public AsyncJobDaoImpl() {
pendingAsyncJobSearch = createSearchBuilder();
pendingAsyncJobSearch.and("instanceType", pendingAsyncJobSearch.entity().getInstanceType(),
SearchCriteria.Op.EQ);
pendingAsyncJobSearch.and("instanceId", pendingAsyncJobSearch.entity().getInstanceId(),
SearchCriteria.Op.EQ);
pendingAsyncJobSearch.and("status", pendingAsyncJobSearch.entity().getStatus(),
SearchCriteria.Op.EQ);
pendingAsyncJobSearch.done();
pendingAsyncJobsSearch = createSearchBuilder();
pendingAsyncJobsSearch.and("instanceType", pendingAsyncJobsSearch.entity().getInstanceType(),
SearchCriteria.Op.EQ);
pendingAsyncJobsSearch.and("accountId", pendingAsyncJobsSearch.entity().getAccountId(),
SearchCriteria.Op.EQ);
pendingAsyncJobsSearch.and("status", pendingAsyncJobsSearch.entity().getStatus(),
SearchCriteria.Op.EQ);
pendingAsyncJobsSearch.done();
expiringUnfinishedAsyncJobSearch = createSearchBuilder();
expiringUnfinishedAsyncJobSearch.and("created", expiringUnfinishedAsyncJobSearch.entity().getCreated(),
SearchCriteria.Op.LTEQ);
expiringUnfinishedAsyncJobSearch.and("completeMsId", expiringUnfinishedAsyncJobSearch.entity().getCompleteMsid(), SearchCriteria.Op.NULL);
expiringUnfinishedAsyncJobSearch.and("jobStatus", expiringUnfinishedAsyncJobSearch.entity().getStatus(), SearchCriteria.Op.EQ);
expiringUnfinishedAsyncJobSearch.done();
expiringCompletedAsyncJobSearch = createSearchBuilder();
expiringCompletedAsyncJobSearch.and("created", expiringCompletedAsyncJobSearch.entity().getCreated(),
SearchCriteria.Op.LTEQ);
expiringCompletedAsyncJobSearch.and("completeMsId", expiringCompletedAsyncJobSearch.entity().getCompleteMsid(), SearchCriteria.Op.NNULL);
expiringCompletedAsyncJobSearch.and("jobStatus", expiringCompletedAsyncJobSearch.entity().getStatus(), SearchCriteria.Op.NEQ);
expiringCompletedAsyncJobSearch.done();
}
public AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId) {
SearchCriteria<AsyncJobVO> sc = pendingAsyncJobSearch.create();
sc.setParameters("instanceType", instanceType);
sc.setParameters("instanceId", instanceId);
sc.setParameters("status", AsyncJobResult.STATUS_IN_PROGRESS);
List<AsyncJobVO> l = listIncludingRemovedBy(sc);
if(l != null && l.size() > 0) {
if(l.size() > 1) {
s_logger.warn("Instance " + instanceType + "-" + instanceId + " has multiple pending async-job");
}
return l.get(0);
}
return null;
}
public List<AsyncJobVO> findInstancePendingAsyncJobs(ApiCommandJobType instanceType, Long accountId) {
SearchCriteria<AsyncJobVO> sc = pendingAsyncJobsSearch.create();
sc.setParameters("instanceType", instanceType);
if (accountId != null) {
sc.setParameters("accountId", accountId);
}
sc.setParameters("status", AsyncJobResult.STATUS_IN_PROGRESS);
return listBy(sc);
}
@Override
public List<AsyncJobVO> getExpiredUnfinishedJobs(Date cutTime, int limit) {
SearchCriteria<AsyncJobVO> sc = expiringUnfinishedAsyncJobSearch.create();
sc.setParameters("created", cutTime);
sc.setParameters("jobStatus", 0);
Filter filter = new Filter(AsyncJobVO.class, "created", true, 0L, (long)limit);
return listIncludingRemovedBy(sc, filter);
}
@Override
public List<AsyncJobVO> getExpiredCompletedJobs(Date cutTime, int limit) {
SearchCriteria<AsyncJobVO> sc = expiringCompletedAsyncJobSearch.create();
sc.setParameters("created", cutTime);
sc.setParameters("jobStatus", 0);
Filter filter = new Filter(AsyncJobVO.class, "created", true, 0L, (long)limit);
return listIncludingRemovedBy(sc, filter);
}
@DB
public void resetJobProcess(long msid, int jobResultCode, String jobResultMessage) {
String sql = "UPDATE async_job SET job_status=" + AsyncJobResult.STATUS_FAILED + ", job_result_code=" + jobResultCode
+ ", job_result='" + jobResultMessage + "' where job_status=0 AND (job_complete_msid=? OR (job_complete_msid IS NULL AND job_init_msid=?))";
Transaction txn = Transaction.currentTxn();
PreparedStatement pstmt = null;
try {
pstmt = txn.prepareAutoCloseStatement(sql);
pstmt.setLong(1, msid);
pstmt.setLong(2, msid);
pstmt.execute();
} catch (SQLException e) {
s_logger.warn("Unable to reset job status for management server " + msid, e);
} catch (Throwable e) {
s_logger.warn("Unable to reset job status for management server " + msid, e);
}
}
}

View File

@ -1,25 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async.dao;
import com.cloud.async.SyncQueueVO;
import com.cloud.utils.db.GenericDao;
public interface SyncQueueDao extends GenericDao<SyncQueueVO, Long>{
public void ensureQueue(String syncObjType, long syncObjId);
public SyncQueueVO find(String syncObjType, long syncObjId);
}

View File

@ -1,81 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async.dao;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;
import java.util.TimeZone;
import javax.ejb.Local;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.async.SyncQueueVO;
import com.cloud.utils.DateUtil;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
@Component
@Local(value = { SyncQueueDao.class })
public class SyncQueueDaoImpl extends GenericDaoBase<SyncQueueVO, Long> implements SyncQueueDao {
private static final Logger s_logger = Logger.getLogger(SyncQueueDaoImpl.class.getName());
SearchBuilder<SyncQueueVO> TypeIdSearch = createSearchBuilder();
@Override
public void ensureQueue(String syncObjType, long syncObjId) {
Date dt = DateUtil.currentGMTTime();
String sql = "INSERT IGNORE INTO sync_queue(sync_objtype, sync_objid, created, last_updated)" +
" values(?, ?, ?, ?)";
Transaction txn = Transaction.currentTxn();
PreparedStatement pstmt = null;
try {
pstmt = txn.prepareAutoCloseStatement(sql);
pstmt.setString(1, syncObjType);
pstmt.setLong(2, syncObjId);
pstmt.setString(3, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), dt));
pstmt.setString(4, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), dt));
pstmt.execute();
} catch (SQLException e) {
s_logger.warn("Unable to create sync queue " + syncObjType + "-" + syncObjId + ":" + e.getMessage(), e);
} catch (Throwable e) {
s_logger.warn("Unable to create sync queue " + syncObjType + "-" + syncObjId + ":" + e.getMessage(), e);
}
}
@Override
public SyncQueueVO find(String syncObjType, long syncObjId) {
SearchCriteria<SyncQueueVO> sc = TypeIdSearch.create();
sc.setParameters("syncObjType", syncObjType);
sc.setParameters("syncObjId", syncObjId);
return findOneBy(sc);
}
protected SyncQueueDaoImpl() {
super();
TypeIdSearch = createSearchBuilder();
TypeIdSearch.and("syncObjType", TypeIdSearch.entity().getSyncObjType(), SearchCriteria.Op.EQ);
TypeIdSearch.and("syncObjId", TypeIdSearch.entity().getSyncObjId(), SearchCriteria.Op.EQ);
TypeIdSearch.done();
}
}

View File

@ -1,30 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async.dao;
import java.util.List;
import com.cloud.async.SyncQueueItemVO;
import com.cloud.utils.db.GenericDao;
public interface SyncQueueItemDao extends GenericDao<SyncQueueItemVO, Long> {
public SyncQueueItemVO getNextQueueItem(long queueId);
public List<SyncQueueItemVO> getNextQueueItems(int maxItems);
public List<SyncQueueItemVO> getActiveQueueItems(Long msid, boolean exclusive);
public List<SyncQueueItemVO> getBlockedQueueItems(long thresholdMs, boolean exclusive);
public Long getQueueItemIdByContentIdAndType(long contentId, String contentType);
}

View File

@ -1,163 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async.dao;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import javax.ejb.Local;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.async.SyncQueueItemVO;
import com.cloud.utils.DateUtil;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.GenericSearchBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.Transaction;
@Component
@Local(value = { SyncQueueItemDao.class })
@DB
public class SyncQueueItemDaoImpl extends GenericDaoBase<SyncQueueItemVO, Long> implements SyncQueueItemDao {
private static final Logger s_logger = Logger.getLogger(SyncQueueItemDaoImpl.class);
final GenericSearchBuilder<SyncQueueItemVO, Long> queueIdSearch;
protected SyncQueueItemDaoImpl() {
super();
queueIdSearch = createSearchBuilder(Long.class);
queueIdSearch.and("contentId", queueIdSearch.entity().getContentId(), Op.EQ);
queueIdSearch.and("contentType", queueIdSearch.entity().getContentType(), Op.EQ);
queueIdSearch.selectField(queueIdSearch.entity().getId());
queueIdSearch.done();
}
@Override
public SyncQueueItemVO getNextQueueItem(long queueId) {
SearchBuilder<SyncQueueItemVO> sb = createSearchBuilder();
sb.and("queueId", sb.entity().getQueueId(), SearchCriteria.Op.EQ);
sb.and("lastProcessNumber", sb.entity().getLastProcessNumber(), SearchCriteria.Op.NULL);
sb.done();
SearchCriteria<SyncQueueItemVO> sc = sb.create();
sc.setParameters("queueId", queueId);
Filter filter = new Filter(SyncQueueItemVO.class, "created", true, 0L, 1L);
List<SyncQueueItemVO> l = listBy(sc, filter);
if(l != null && l.size() > 0)
return l.get(0);
return null;
}
@Override
public List<SyncQueueItemVO> getNextQueueItems(int maxItems) {
List<SyncQueueItemVO> l = new ArrayList<SyncQueueItemVO>();
String sql = "SELECT i.id, i.queue_id, i.content_type, i.content_id, i.created " +
" FROM sync_queue AS q JOIN sync_queue_item AS i ON q.id = i.queue_id " +
" WHERE q.queue_size < q.queue_size_limit AND i.queue_proc_number IS NULL " +
" GROUP BY q.id " +
" ORDER BY i.id " +
" LIMIT 0, ?";
Transaction txn = Transaction.currentTxn();
PreparedStatement pstmt = null;
try {
pstmt = txn.prepareAutoCloseStatement(sql);
pstmt.setInt(1, maxItems);
ResultSet rs = pstmt.executeQuery();
while(rs.next()) {
SyncQueueItemVO item = new SyncQueueItemVO();
item.setId(rs.getLong(1));
item.setQueueId(rs.getLong(2));
item.setContentType(rs.getString(3));
item.setContentId(rs.getLong(4));
item.setCreated(DateUtil.parseDateString(TimeZone.getTimeZone("GMT"), rs.getString(5)));
l.add(item);
}
} catch (SQLException e) {
s_logger.error("Unexpected sql excetpion, ", e);
} catch (Throwable e) {
s_logger.error("Unexpected excetpion, ", e);
}
return l;
}
@Override
public List<SyncQueueItemVO> getActiveQueueItems(Long msid, boolean exclusive) {
SearchBuilder<SyncQueueItemVO> sb = createSearchBuilder();
sb.and("lastProcessMsid", sb.entity().getLastProcessMsid(),
SearchCriteria.Op.EQ);
sb.done();
SearchCriteria<SyncQueueItemVO> sc = sb.create();
sc.setParameters("lastProcessMsid", msid);
Filter filter = new Filter(SyncQueueItemVO.class, "created", true, null, null);
if(exclusive)
return lockRows(sc, filter, true);
return listBy(sc, filter);
}
@Override
public List<SyncQueueItemVO> getBlockedQueueItems(long thresholdMs, boolean exclusive) {
Date cutTime = DateUtil.currentGMTTime();
SearchBuilder<SyncQueueItemVO> sbItem = createSearchBuilder();
sbItem.and("lastProcessMsid", sbItem.entity().getLastProcessMsid(), SearchCriteria.Op.NNULL);
sbItem.and("lastProcessNumber", sbItem.entity().getLastProcessNumber(), SearchCriteria.Op.NNULL);
sbItem.and("lastProcessNumber", sbItem.entity().getLastProcessTime(), SearchCriteria.Op.NNULL);
sbItem.and("lastProcessTime2", sbItem.entity().getLastProcessTime(), SearchCriteria.Op.LT);
sbItem.done();
SearchCriteria<SyncQueueItemVO> sc = sbItem.create();
sc.setParameters("lastProcessTime2", new Date(cutTime.getTime() - thresholdMs));
if(exclusive)
return lockRows(sc, null, true);
return listBy(sc, null);
}
@Override
public Long getQueueItemIdByContentIdAndType(long contentId, String contentType) {
SearchCriteria<Long> sc = queueIdSearch.create();
sc.setParameters("contentId", contentId);
sc.setParameters("contentType", contentType);
List<Long> id = customSearch(sc, null);
return id.size() == 0 ? null : id.get(0);
}
}

View File

@ -1,183 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF 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 com.cloud.async.executor;
import java.util.Date;
import com.cloud.async.AsyncInstanceCreateStatus;
import com.cloud.serializer.Param;
import com.cloud.storage.Volume.Type;
import com.cloud.storage.upload.UploadState;
public class ExtractJobResultObject {
public ExtractJobResultObject(Long accountId, String typeName, String currState, int uploadPercent, Long uploadId){
this.accountId = accountId;
this.name = typeName;
this.state = currState;
this.id = uploadId;
this.uploadPercent = uploadPercent;
}
public ExtractJobResultObject(Long accountId, String typeName, String currState, Long uploadId, String url){
this.accountId = accountId;
this.name = typeName;
this.state = currState;
this.id = uploadId;
this.url = url;
}
public ExtractJobResultObject(){
}
@Param(name="id")
private long id;
@Param(name="name")
private String name;
@Param(name="uploadPercentage")
private int uploadPercent;
@Param(name="uploadStatus")
private String uploadStatus;
@Param(name="accountid")
long accountId;
@Param(name="result_string")
String result_string;
@Param(name="created")
private Date createdDate;
@Param(name="state")
private String state;
@Param(name="storagetype")
String storageType;
@Param(name="storage")
private String storage;
@Param(name="zoneid")
private Long zoneId;
@Param(name="zonename")
private String zoneName;
@Param(name="url")
private String url;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getUploadPercent() {
return uploadPercent;
}
public void setUploadPercent(int i) {
this.uploadPercent = i;
}
public String getUploadStatus() {
return uploadStatus;
}
public void setUploadStatus(String uploadStatus) {
this.uploadStatus = uploadStatus;
}
public String getResult_string() {
return result_string;
}
public void setResult_string(String resultString) {
result_string = resultString;
}
public Long getZoneId() {
return zoneId;
}
public void setZoneId(Long zoneId) {
this.zoneId = zoneId;
}
public String getZoneName() {
return zoneName;
}
public void setZoneName(String zoneName) {
this.zoneName = zoneName;
}
public String getStorage() {
return storage;
}
public void setStorage(String storage) {
this.storage = storage;
}
public void setId(long id) {
this.id = id;
}
public long getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
public Date getCreatedDate() {
return createdDate;
}
public void setState(String status) {
this.state = status;
}
public String getState() {
return state;
}
public void setStorageType (String storageType) {
this.storageType = storageType;
}
public String getStorageType() {
return storageType;
}
}

View File

@ -68,6 +68,10 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.framework.async.AsyncCallFuture;
import org.apache.cloudstack.framework.jobs.AsyncJob;
import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
import org.apache.cloudstack.storage.command.AttachAnswer; import org.apache.cloudstack.storage.command.AttachAnswer;
import org.apache.cloudstack.storage.command.AttachCommand; import org.apache.cloudstack.storage.command.AttachCommand;
import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.command.CommandResult;
@ -88,10 +92,6 @@ import com.cloud.agent.api.to.DiskTO;
import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.alert.AlertManager; import com.cloud.alert.AlertManager;
import com.cloud.api.ApiDBUtils; import com.cloud.api.ApiDBUtils;
import com.cloud.async.AsyncJobExecutor;
import com.cloud.async.AsyncJobManager;
import com.cloud.async.AsyncJobVO;
import com.cloud.async.BaseAsyncJobExecutor;
import com.cloud.capacity.CapacityManager; import com.cloud.capacity.CapacityManager;
import com.cloud.capacity.dao.CapacityDao; import com.cloud.capacity.dao.CapacityDao;
import com.cloud.configuration.Config; import com.cloud.configuration.Config;
@ -1869,21 +1869,20 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
} }
AsyncJobExecutor asyncExecutor = BaseAsyncJobExecutor AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
.getCurrentExecutor();
if (asyncExecutor != null) { if (asyncExecutionContext != null) {
AsyncJobVO job = asyncExecutor.getJob(); AsyncJob job = asyncExecutionContext.getJob();
if (s_logger.isInfoEnabled()) { if (s_logger.isInfoEnabled()) {
s_logger.info("Trying to attaching volume " + volumeId s_logger.info("Trying to attaching volume " + volumeId
+ " to vm instance:" + vm.getId() + " to vm instance:" + vm.getId()
+ ", update async job-" + job.getId() + " = [ " + job.getUuid() + ", update async job-" + job.getId()
+ " ] progress status"); + " progress status");
} }
_asyncMgr.updateAsyncJobAttachment(job.getId(), "volume", volumeId); _asyncMgr.updateAsyncJobAttachment(job.getId(), "volume", volumeId);
_asyncMgr.updateAsyncJobStatus(job.getId(), _asyncMgr.updateAsyncJobStatus(job.getId(), BaseCmd.PROGRESS_INSTANCE_CREATED, Long.toString(volumeId));
BaseCmd.PROGRESS_INSTANCE_CREATED, volumeId);
} }
VolumeVO newVol = _volumeDao.findById(volumeOnPrimaryStorage.getId()); VolumeVO newVol = _volumeDao.findById(volumeOnPrimaryStorage.getId());
@ -1969,28 +1968,19 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
"Please specify a VM that is either running or stopped."); "Please specify a VM that is either running or stopped.");
} }
// Check if the VM has VM snapshots AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId); if (asyncExecutionContext != null) {
if(vmSnapshots.size() > 0){ AsyncJob job = asyncExecutionContext.getJob();
throw new InvalidParameterValueException(
"Unable to detach volume, the specified volume is attached to a VM that has VM snapshots.");
}
AsyncJobExecutor asyncExecutor = BaseAsyncJobExecutor
.getCurrentExecutor();
if (asyncExecutor != null) {
AsyncJobVO job = asyncExecutor.getJob();
if (s_logger.isInfoEnabled()) { if (s_logger.isInfoEnabled()) {
s_logger.info("Trying to attaching volume " + volumeId s_logger.info("Trying to attaching volume " + volumeId
+ "to vm instance:" + vm.getId() + "to vm instance:" + vm.getId()
+ ", update async job-" + job.getId() + " = [ " + job.getUuid() + ", update async job-" + job.getId()
+ " ] progress status"); + " progress status");
} }
_asyncMgr.updateAsyncJobAttachment(job.getId(), "volume", volumeId); _asyncMgr.updateAsyncJobAttachment(job.getId(), "volume", volumeId);
_asyncMgr.updateAsyncJobStatus(job.getId(), _asyncMgr.updateAsyncJobStatus(job.getId(), BaseCmd.PROGRESS_INSTANCE_CREATED, volumeId.toString());
BaseCmd.PROGRESS_INSTANCE_CREATED, volumeId);
} }
String errorMsg = "Failed to detach volume: " + volume.getName() String errorMsg = "Failed to detach volume: " + volume.getName()

View File

@ -22,25 +22,26 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import java.util.UUID;
import javax.ejb.Local; import javax.ejb.Local;
import javax.inject.Inject; import javax.inject.Inject;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
import com.cloud.event.ActionEventUtils;
import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotCmd;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotCmd;
import org.apache.cloudstack.context.ServerContexts;
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
import org.apache.cloudstack.framework.jobs.dao.AsyncJobDao;
import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
import com.cloud.api.ApiDispatcher; import com.cloud.api.ApiDispatcher;
import com.cloud.api.ApiGsonHelper; import com.cloud.api.ApiGsonHelper;
import com.cloud.user.Account;
import com.cloud.async.AsyncJobManager;
import com.cloud.async.AsyncJobResult;
import com.cloud.async.AsyncJobVO;
import com.cloud.async.dao.AsyncJobDao;
import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.event.ActionEventUtils;
import com.cloud.event.EventTypes; import com.cloud.event.EventTypes;
import com.cloud.storage.Snapshot; import com.cloud.storage.Snapshot;
import com.cloud.storage.SnapshotPolicyVO; import com.cloud.storage.SnapshotPolicyVO;
@ -55,7 +56,6 @@ import com.cloud.user.User;
import com.cloud.utils.DateUtil; import com.cloud.utils.DateUtil;
import com.cloud.utils.DateUtil.IntervalType; import com.cloud.utils.DateUtil.IntervalType;
import com.cloud.utils.NumbersUtil; import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.ComponentContext; import com.cloud.utils.component.ComponentContext;
import com.cloud.utils.component.ManagerBase; import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.concurrency.TestClock; import com.cloud.utils.concurrency.TestClock;
@ -69,7 +69,8 @@ import com.cloud.utils.db.SearchCriteria;
public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotScheduler { public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotScheduler {
private static final Logger s_logger = Logger.getLogger(SnapshotSchedulerImpl.class); private static final Logger s_logger = Logger.getLogger(SnapshotSchedulerImpl.class);
@Inject protected AsyncJobDao _asyncJobDao; @Inject
protected AsyncJobDao _asyncJobDao;
@Inject protected SnapshotDao _snapshotDao; @Inject protected SnapshotDao _snapshotDao;
@Inject protected SnapshotScheduleDao _snapshotScheduleDao; @Inject protected SnapshotScheduleDao _snapshotScheduleDao;
@Inject protected SnapshotPolicyDao _snapshotPolicyDao; @Inject protected SnapshotPolicyDao _snapshotPolicyDao;
@ -142,14 +143,14 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
Long asyncJobId = snapshotSchedule.getAsyncJobId(); Long asyncJobId = snapshotSchedule.getAsyncJobId();
AsyncJobVO asyncJob = _asyncJobDao.findById(asyncJobId); AsyncJobVO asyncJob = _asyncJobDao.findById(asyncJobId);
switch (asyncJob.getStatus()) { switch (asyncJob.getStatus()) {
case AsyncJobResult.STATUS_SUCCEEDED: case SUCCEEDED:
// The snapshot has been successfully backed up. // The snapshot has been successfully backed up.
// The snapshot state has also been cleaned up. // The snapshot state has also been cleaned up.
// We can schedule the next job for this snapshot. // We can schedule the next job for this snapshot.
// Remove the existing entry in the snapshot_schedule table. // Remove the existing entry in the snapshot_schedule table.
scheduleNextSnapshotJob(snapshotSchedule); scheduleNextSnapshotJob(snapshotSchedule);
break; break;
case AsyncJobResult.STATUS_FAILED: case FAILED:
// Check the snapshot status. // Check the snapshot status.
Long snapshotId = snapshotSchedule.getSnapshotId(); Long snapshotId = snapshotSchedule.getSnapshotId();
if (snapshotId == null) { if (snapshotId == null) {
@ -187,7 +188,7 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
} }
break; break;
case AsyncJobResult.STATUS_IN_PROGRESS: case IN_PROGRESS:
// There is no way of knowing from here whether // There is no way of knowing from here whether
// 1) Another management server is processing this snapshot job // 1) Another management server is processing this snapshot job
// 2) The management server has crashed and this snapshot is lying // 2) The management server has crashed and this snapshot is lying
@ -248,9 +249,9 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
params.put("id", ""+cmd.getEntityId()); params.put("id", ""+cmd.getEntityId());
params.put("ctxStartEventId", "1"); params.put("ctxStartEventId", "1");
AsyncJobVO job = new AsyncJobVO(User.UID_SYSTEM, volume.getAccountId(), CreateSnapshotCmd.class.getName(), AsyncJobVO job = new AsyncJobVO(UUID.randomUUID().toString(), User.UID_SYSTEM, volume.getAccountId(), CreateSnapshotCmd.class.getName(),
ApiGsonHelper.getBuilder().create().toJson(params), cmd.getEntityId(), ApiGsonHelper.getBuilder().create().toJson(params), cmd.getEntityId(),
cmd.getInstanceType()); cmd.getInstanceType() != null ? cmd.getInstanceType().toString() : null);
long jobId = _asyncMgr.submitAsyncJob(job); long jobId = _asyncMgr.submitAsyncJob(job);
@ -373,11 +374,14 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
TimerTask timerTask = new TimerTask() { TimerTask timerTask = new TimerTask() {
@Override @Override
public void run() { public void run() {
ServerContexts.registerSystemContext();
try { try {
Date currentTimestamp = new Date(); Date currentTimestamp = new Date();
poll(currentTimestamp); poll(currentTimestamp);
} catch (Throwable t) { } catch (Throwable t) {
s_logger.warn("Catch throwable in snapshot scheduler " + t.toString(), t); s_logger.warn("Catch throwable in snapshot scheduler ", t);
} finally {
ServerContexts.unregisterSystemContext();
} }
} }
}; };

View File

@ -25,6 +25,9 @@ import java.util.TimerTask;
import javax.inject.Inject; import javax.inject.Inject;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.command.user.iso.ExtractIsoCmd; import org.apache.cloudstack.api.command.user.iso.ExtractIsoCmd;
import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd; import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd; import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd;
@ -33,8 +36,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.log4j.Level; import org.apache.cloudstack.framework.jobs.AsyncJobManager;
import org.apache.log4j.Logger; import org.apache.cloudstack.jobs.JobInfo;
import com.cloud.agent.Listener; import com.cloud.agent.Listener;
import com.cloud.agent.api.AgentControlAnswer; import com.cloud.agent.api.AgentControlAnswer;
@ -48,8 +51,7 @@ import com.cloud.agent.api.storage.UploadCommand;
import com.cloud.agent.api.storage.UploadProgressCommand; import com.cloud.agent.api.storage.UploadProgressCommand;
import com.cloud.agent.api.storage.UploadProgressCommand.RequestType; import com.cloud.agent.api.storage.UploadProgressCommand.RequestType;
import com.cloud.api.ApiDBUtils; import com.cloud.api.ApiDBUtils;
import com.cloud.async.AsyncJobManager; import com.cloud.api.ApiSerializerHelper;
import com.cloud.async.AsyncJobResult;
import com.cloud.host.Host; import com.cloud.host.Host;
import com.cloud.storage.Storage; import com.cloud.storage.Storage;
import com.cloud.storage.Upload.Status; import com.cloud.storage.Upload.Status;
@ -66,7 +68,7 @@ public class UploadListener implements Listener {
private final RequestType reqType; private final RequestType reqType;
public StatusTask(UploadListener ul, RequestType req) { public StatusTask(UploadListener ul, RequestType req) {
this.reqType = req; reqType = req;
this.ul = ul; this.ul = ul;
} }
@ -167,19 +169,19 @@ public class UploadListener implements Listener {
public UploadListener(DataStore host, Timer _timer, UploadDao uploadDao, public UploadListener(DataStore host, Timer _timer, UploadDao uploadDao,
UploadVO uploadObj, UploadMonitorImpl uploadMonitor, UploadCommand cmd, UploadVO uploadObj, UploadMonitorImpl uploadMonitor, UploadCommand cmd,
Long accountId, String typeName, Type type, long eventId, long asyncJobId, AsyncJobManager asyncMgr) { Long accountId, String typeName, Type type, long eventId, long asyncJobId, AsyncJobManager asyncMgr) {
this.sserver = host; sserver = host;
this.uploadDao = uploadDao; this.uploadDao = uploadDao;
this.uploadMonitor = uploadMonitor; this.uploadMonitor = uploadMonitor;
this.cmd = cmd; this.cmd = cmd;
this.uploadId = uploadObj.getId(); uploadId = uploadObj.getId();
this.accountId = accountId; this.accountId = accountId;
this.typeName = typeName; this.typeName = typeName;
this.type = type; this.type = type;
initStateMachine(); initStateMachine();
this.currState = getState(Status.NOT_UPLOADED.toString()); currState = getState(Status.NOT_UPLOADED.toString());
this.timer = _timer; timer = _timer;
this.timeoutTask = new TimeoutTask(this); timeoutTask = new TimeoutTask(this);
this.timer.schedule(timeoutTask, 3 * STATUS_POLL_INTERVAL); timer.schedule(timeoutTask, 3 * STATUS_POLL_INTERVAL);
this.eventId = eventId; this.eventId = eventId;
this.asyncJobId = asyncJobId; this.asyncJobId = asyncJobId;
this.asyncMgr = asyncMgr; this.asyncMgr = asyncMgr;
@ -190,7 +192,7 @@ public class UploadListener implements Listener {
else { else {
extractId = ApiDBUtils.findTemplateById(uploadObj.getTypeId()).getUuid(); extractId = ApiDBUtils.findTemplateById(uploadObj.getTypeId()).getUuid();
} }
this.resultObj = new ExtractResponse(extractId, typeName, ApiDBUtils.findAccountById(accountId).getUuid(), Status.NOT_UPLOADED.toString(), resultObj = new ExtractResponse(extractId, typeName, ApiDBUtils.findAccountById(accountId).getUuid(), Status.NOT_UPLOADED.toString(),
ApiDBUtils.findUploadById(uploadId).getUuid()); ApiDBUtils.findUploadById(uploadId).getUuid());
resultObj.setResponseName(responseNameMap.get(type.toString())); resultObj.setResponseName(responseNameMap.get(type.toString()));
updateDatabase(Status.NOT_UPLOADED, cmd.getUrl(), ""); updateDatabase(Status.NOT_UPLOADED, cmd.getUrl(), "");
@ -215,11 +217,11 @@ public class UploadListener implements Listener {
} }
public void setCommand(UploadCommand _cmd) { public void setCommand(UploadCommand _cmd) {
this.cmd = _cmd; cmd = _cmd;
} }
public void setJobId(String _jobId) { public void setJobId(String _jobId) {
this.jobId = _jobId; jobId = _jobId;
} }
public String getJobId() { public String getJobId() {
@ -370,7 +372,7 @@ public class UploadListener implements Listener {
resultObj.setResultString(uploadErrorString); resultObj.setResultString(uploadErrorString);
resultObj.setState(state.toString()); resultObj.setState(state.toString());
asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 1L); asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 1L);
asyncMgr.updateAsyncJobStatus(asyncJobId, AsyncJobResult.STATUS_IN_PROGRESS, resultObj); asyncMgr.updateAsyncJobStatus(asyncJobId, JobInfo.Status.IN_PROGRESS.ordinal(), ApiSerializerHelper.toSerializedString(resultObj));
UploadVO vo = uploadDao.createForUpdate(); UploadVO vo = uploadDao.createForUpdate();
vo.setUploadState(state); vo.setUploadState(state);
@ -383,7 +385,7 @@ public class UploadListener implements Listener {
resultObj.setResultString(uploadErrorString); resultObj.setResultString(uploadErrorString);
resultObj.setState(state.toString()); resultObj.setState(state.toString());
asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 1L); asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 1L);
asyncMgr.updateAsyncJobStatus(asyncJobId, AsyncJobResult.STATUS_IN_PROGRESS, resultObj); asyncMgr.updateAsyncJobStatus(asyncJobId, JobInfo.Status.IN_PROGRESS.ordinal(), ApiSerializerHelper.toSerializedString(resultObj));
UploadVO vo = uploadDao.createForUpdate(); UploadVO vo = uploadDao.createForUpdate();
vo.setUploadState(state); vo.setUploadState(state);
@ -411,12 +413,12 @@ public class UploadListener implements Listener {
if (answer.getUploadStatus() == Status.UPLOAD_IN_PROGRESS) { if (answer.getUploadStatus() == Status.UPLOAD_IN_PROGRESS) {
asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 1L); asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 1L);
asyncMgr.updateAsyncJobStatus(asyncJobId, AsyncJobResult.STATUS_IN_PROGRESS, resultObj); asyncMgr.updateAsyncJobStatus(asyncJobId, JobInfo.Status.IN_PROGRESS.ordinal(), ApiSerializerHelper.toSerializedString(resultObj));
} else if (answer.getUploadStatus() == Status.UPLOADED) { } else if (answer.getUploadStatus() == Status.UPLOADED) {
resultObj.setResultString("Success"); resultObj.setResultString("Success");
asyncMgr.completeAsyncJob(asyncJobId, AsyncJobResult.STATUS_SUCCEEDED, 1, resultObj); asyncMgr.completeAsyncJob(asyncJobId, JobInfo.Status.SUCCEEDED, 1, ApiSerializerHelper.toSerializedString(resultObj));
} else { } else {
asyncMgr.completeAsyncJob(asyncJobId, AsyncJobResult.STATUS_FAILED, 2, resultObj); asyncMgr.completeAsyncJob(asyncJobId, JobInfo.Status.FAILED, 2, ApiSerializerHelper.toSerializedString(resultObj));
} }
UploadVO updateBuilder = uploadDao.createForUpdate(); UploadVO updateBuilder = uploadDao.createForUpdate();
updateBuilder.setUploadPercent(answer.getUploadPct()); updateBuilder.setUploadPercent(answer.getUploadPct());
@ -460,7 +462,7 @@ public class UploadListener implements Listener {
} }
public void setCurrState(Status uploadState) { public void setCurrState(Status uploadState) {
this.currState = getState(currState.toString()); currState = getState(currState.toString());
} }
public static class Callback implements AsyncCompletionCallback<Answer> { public static class Callback implements AsyncCompletionCallback<Answer> {

View File

@ -18,16 +18,14 @@ package com.cloud.storage.upload;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
import com.cloud.async.AsyncJobManager;
import com.cloud.host.HostVO;
import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Upload.Mode; import com.cloud.storage.Upload.Mode;
import com.cloud.storage.Upload.Status; import com.cloud.storage.Upload.Status;
import com.cloud.storage.Upload.Type; import com.cloud.storage.Upload.Type;
import com.cloud.storage.UploadVO; import com.cloud.storage.UploadVO;
import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VolumeVO; import com.cloud.storage.VolumeVO;
import com.cloud.utils.component.Manager; import com.cloud.utils.component.Manager;

View File

@ -32,15 +32,17 @@ import javax.ejb.Local;
import javax.inject.Inject; import javax.inject.Inject;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.agent.AgentManager; import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer; import com.cloud.agent.api.Answer;
@ -49,7 +51,6 @@ import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
import com.cloud.agent.api.storage.UploadCommand; import com.cloud.agent.api.storage.UploadCommand;
import com.cloud.agent.api.storage.UploadProgressCommand.RequestType; import com.cloud.agent.api.storage.UploadProgressCommand.RequestType;
import com.cloud.api.ApiDBUtils; import com.cloud.api.ApiDBUtils;
import com.cloud.async.AsyncJobManager;
import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.host.Host; import com.cloud.host.Host;
import com.cloud.host.HostVO; import com.cloud.host.HostVO;
@ -180,7 +181,7 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor {
Type type = (template.getFormat() == ImageFormat.ISO) ? Type.ISO : Type.TEMPLATE ; Type type = (template.getFormat() == ImageFormat.ISO) ? Type.ISO : Type.TEMPLATE ;
DataStore secStore = this.storeMgr.getImageStore(dataCenterId); DataStore secStore = storeMgr.getImageStore(dataCenterId);
UploadVO uploadTemplateObj = new UploadVO(secStore.getId(), template.getId(), new Date(), UploadVO uploadTemplateObj = new UploadVO(secStore.getId(), template.getId(), new Date(),
Upload.Status.NOT_UPLOADED, type, url, Mode.FTP_UPLOAD); Upload.Status.NOT_UPLOADED, type, url, Mode.FTP_UPLOAD);
@ -212,7 +213,7 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor {
Type type = (template.getFormat() == ImageFormat.ISO) ? Type.ISO : Type.TEMPLATE ; Type type = (template.getFormat() == ImageFormat.ISO) ? Type.ISO : Type.TEMPLATE ;
// find an endpoint to send command // find an endpoint to send command
DataStore store = this.storeMgr.getDataStore(vmTemplateHost.getDataStoreId(), DataStoreRole.Image); DataStore store = storeMgr.getDataStore(vmTemplateHost.getDataStoreId(), DataStoreRole.Image);
EndPoint ep = _epSelector.select(store); EndPoint ep = _epSelector.select(store);
//Check if it already exists. //Check if it already exists.
@ -299,7 +300,7 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor {
// Create Symlink at ssvm // Create Symlink at ssvm
String uuid = UUID.randomUUID().toString() + "." + format.toString().toLowerCase() ; String uuid = UUID.randomUUID().toString() + "." + format.toString().toLowerCase() ;
DataStore secStore = this.storeMgr.getDataStore(ApiDBUtils.findUploadById(uploadId).getDataStoreId(), DataStoreRole.Image); DataStore secStore = storeMgr.getDataStore(ApiDBUtils.findUploadById(uploadId).getDataStoreId(), DataStoreRole.Image);
EndPoint ep = _epSelector.select(secStore); EndPoint ep = _epSelector.select(secStore);
if( ep == null ) { if( ep == null ) {
errorString = "There is no secondary storage VM for secondary storage host " + secStore.getName(); errorString = "There is no secondary storage VM for secondary storage host " + secStore.getName();
@ -484,7 +485,7 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor {
for (UploadVO extractJob : extractJobs){ for (UploadVO extractJob : extractJobs){
if( getTimeDiff(extractJob.getLastUpdated()) > EXTRACT_URL_LIFE_LIMIT_IN_SECONDS ){ if( getTimeDiff(extractJob.getLastUpdated()) > EXTRACT_URL_LIFE_LIMIT_IN_SECONDS ){
String path = extractJob.getInstallPath(); String path = extractJob.getInstallPath();
DataStore secStore = this.storeMgr.getDataStore(extractJob.getDataStoreId(), DataStoreRole.Image); DataStore secStore = storeMgr.getDataStore(extractJob.getDataStoreId(), DataStoreRole.Image);
// Would delete the symlink for the Type and if Type == VOLUME then also the volume // Would delete the symlink for the Type and if Type == VOLUME then also the volume

View File

@ -30,6 +30,9 @@ import javax.ejb.Local;
import javax.inject.Inject; import javax.inject.Inject;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.api.BaseListTemplateOrIsoPermissionsCmd; import org.apache.cloudstack.api.BaseListTemplateOrIsoPermissionsCmd;
import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoCmd; import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoCmd;
@ -55,18 +58,18 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.framework.async.AsyncCallFuture;
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
import org.apache.cloudstack.storage.command.AttachCommand; import org.apache.cloudstack.storage.command.AttachCommand;
import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.command.CommandResult;
import org.apache.cloudstack.storage.command.DettachCommand; import org.apache.cloudstack.storage.command.DettachCommand;
@ -77,9 +80,6 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.agent.AgentManager; import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer; import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command; import com.cloud.agent.api.Command;
@ -91,7 +91,6 @@ import com.cloud.agent.api.to.NfsTO;
import com.cloud.api.ApiDBUtils; import com.cloud.api.ApiDBUtils;
import com.cloud.api.query.dao.UserVmJoinDao; import com.cloud.api.query.dao.UserVmJoinDao;
import com.cloud.api.query.vo.UserVmJoinVO; import com.cloud.api.query.vo.UserVmJoinVO;
import com.cloud.async.AsyncJobManager;
import com.cloud.configuration.Config; import com.cloud.configuration.Config;
import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.Resource.ResourceType;
import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.configuration.dao.ConfigurationDao;
@ -119,27 +118,27 @@ import com.cloud.projects.Project;
import com.cloud.projects.ProjectManager; import com.cloud.projects.ProjectManager;
import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceManager;
import com.cloud.server.ConfigurationServer; import com.cloud.server.ConfigurationServer;
import com.cloud.storage.DataStoreRole;
import com.cloud.storage.GuestOSVO; import com.cloud.storage.GuestOSVO;
import com.cloud.storage.LaunchPermissionVO; import com.cloud.storage.LaunchPermissionVO;
import com.cloud.storage.ScopeType;
import com.cloud.storage.Snapshot; import com.cloud.storage.Snapshot;
import com.cloud.storage.SnapshotVO; import com.cloud.storage.SnapshotVO;
import com.cloud.storage.Storage; import com.cloud.storage.Storage;
import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.Storage.TemplateType;
import com.cloud.storage.DataStoreRole;
import com.cloud.storage.ScopeType;
import com.cloud.storage.StorageManager; import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePool;
import com.cloud.storage.StoragePoolHostVO; import com.cloud.storage.StoragePoolHostVO;
import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.StoragePoolStatus;
import com.cloud.storage.TemplateProfile; import com.cloud.storage.TemplateProfile;
import com.cloud.storage.Upload; import com.cloud.storage.Upload;
import com.cloud.storage.VMTemplateZoneVO;
import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateStoragePoolVO; import com.cloud.storage.VMTemplateStoragePoolVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VMTemplateZoneVO;
import com.cloud.storage.Volume; import com.cloud.storage.Volume;
import com.cloud.storage.VolumeManager; import com.cloud.storage.VolumeManager;
import com.cloud.storage.VolumeVO; import com.cloud.storage.VolumeVO;
@ -175,7 +174,8 @@ import com.cloud.utils.Pair;
import com.cloud.utils.component.AdapterBase; import com.cloud.utils.component.AdapterBase;
import com.cloud.utils.component.ManagerBase; import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.*; import com.cloud.utils.db.DB;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.UserVmManager; import com.cloud.vm.UserVmManager;
import com.cloud.vm.UserVmVO; import com.cloud.vm.UserVmVO;
@ -361,9 +361,9 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
public DataStore getImageStore(String storeUuid, Long zoneId) { public DataStore getImageStore(String storeUuid, Long zoneId) {
DataStore imageStore = null; DataStore imageStore = null;
if (storeUuid != null) { if (storeUuid != null) {
imageStore = this._dataStoreMgr.getDataStore(storeUuid, DataStoreRole.Image); imageStore = _dataStoreMgr.getDataStore(storeUuid, DataStoreRole.Image);
} else { } else {
List<DataStore> stores = this._dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId)); List<DataStore> stores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId));
if (stores.size() > 1) { if (stores.size() > 1) {
throw new CloudRuntimeException("multiple image stores, don't know which one to use"); throw new CloudRuntimeException("multiple image stores, don't know which one to use");
} }
@ -464,13 +464,13 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
_accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template); _accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template);
List<DataStore> ssStores = this._dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId)); List<DataStore> ssStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId));
TemplateDataStoreVO tmpltStoreRef = null; TemplateDataStoreVO tmpltStoreRef = null;
ImageStoreEntity tmpltStore = null; ImageStoreEntity tmpltStore = null;
if (ssStores != null) { if (ssStores != null) {
for (DataStore store : ssStores) { for (DataStore store : ssStores) {
tmpltStoreRef = this._tmplStoreDao.findByStoreTemplate(store.getId(), templateId); tmpltStoreRef = _tmplStoreDao.findByStoreTemplate(store.getId(), templateId);
if (tmpltStoreRef != null) { if (tmpltStoreRef != null) {
if (tmpltStoreRef.getDownloadState() == com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { if (tmpltStoreRef.getDownloadState() == com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
tmpltStore = (ImageStoreEntity) store; tmpltStore = (ImageStoreEntity) store;
@ -494,7 +494,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
for (final StoragePoolVO pool : pools) { for (final StoragePoolVO pool : pools) {
if (pool.getDataCenterId() == zoneId) { if (pool.getDataCenterId() == zoneId) {
s_logger.info("Schedule to preload template " + template.getId() + " into primary storage " + pool.getId()); s_logger.info("Schedule to preload template " + template.getId() + " into primary storage " + pool.getId());
this._preloadExecutor.execute(new Runnable() { _preloadExecutor.execute(new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
@ -542,7 +542,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
} }
} }
templateStoreRef = this._tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, pool.getDataCenterId(), templateStoreRef = _tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, pool.getDataCenterId(),
VMTemplateStorageResourceAssoc.Status.DOWNLOADED); VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
if (templateStoreRef == null) { if (templateStoreRef == null) {
s_logger.error("Unable to find a secondary storage host who has completely downloaded the template."); s_logger.error("Unable to find a secondary storage host who has completely downloaded the template.");
@ -559,10 +559,10 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
if (s_logger.isDebugEnabled()) { if (s_logger.isDebugEnabled()) {
s_logger.debug("Downloading template " + templateId + " to pool " + poolId); s_logger.debug("Downloading template " + templateId + " to pool " + poolId);
} }
DataStore srcSecStore = this._dataStoreMgr.getDataStore(templateStoreRef.getDataStoreId(), DataStoreRole.Image); DataStore srcSecStore = _dataStoreMgr.getDataStore(templateStoreRef.getDataStoreId(), DataStoreRole.Image);
TemplateInfo srcTemplate = this._tmplFactory.getTemplate(templateId, srcSecStore); TemplateInfo srcTemplate = _tmplFactory.getTemplate(templateId, srcSecStore);
AsyncCallFuture<TemplateApiResult> future = this._tmpltSvr.prepareTemplateOnPrimary(srcTemplate, pool); AsyncCallFuture<TemplateApiResult> future = _tmpltSvr.prepareTemplateOnPrimary(srcTemplate, pool);
try { try {
TemplateApiResult result = future.get(); TemplateApiResult result = future.get();
if (result.isFailed()) { if (result.isFailed()) {
@ -619,13 +619,13 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
long tmpltId = template.getId(); long tmpltId = template.getId();
long dstZoneId = dstZone.getId(); long dstZoneId = dstZone.getId();
// find all eligible image stores for the destination zone // find all eligible image stores for the destination zone
List<DataStore> dstSecStores = this._dataStoreMgr.getImageStoresByScope(new ZoneScope(dstZoneId)); List<DataStore> dstSecStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(dstZoneId));
if (dstSecStores == null || dstSecStores.isEmpty()) { if (dstSecStores == null || dstSecStores.isEmpty()) {
throw new StorageUnavailableException("Destination zone is not ready, no image store associated", DataCenter.class, dstZone.getId()); throw new StorageUnavailableException("Destination zone is not ready, no image store associated", DataCenter.class, dstZone.getId());
} }
AccountVO account = _accountDao.findById(template.getAccountId()); AccountVO account = _accountDao.findById(template.getAccountId());
// find the size of the template to be copied // find the size of the template to be copied
TemplateDataStoreVO srcTmpltStore = this._tmplStoreDao.findByStoreTemplate(srcSecStore.getId(), tmpltId); TemplateDataStoreVO srcTmpltStore = _tmplStoreDao.findByStoreTemplate(srcSecStore.getId(), tmpltId);
_resourceLimitMgr.checkResourceLimit(account, ResourceType.template); _resourceLimitMgr.checkResourceLimit(account, ResourceType.template);
_resourceLimitMgr.checkResourceLimit(account, ResourceType.secondary_storage, new Long(srcTmpltStore.getSize())); _resourceLimitMgr.checkResourceLimit(account, ResourceType.secondary_storage, new Long(srcTmpltStore.getSize()));
@ -641,17 +641,17 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
createEventType = EventTypes.EVENT_TEMPLATE_CREATE; createEventType = EventTypes.EVENT_TEMPLATE_CREATE;
} }
TemplateInfo srcTemplate = this._tmplFactory.getTemplate(template.getId(), srcSecStore); TemplateInfo srcTemplate = _tmplFactory.getTemplate(template.getId(), srcSecStore);
// Copy will just find one eligible image store for the destination zone // Copy will just find one eligible image store for the destination zone
// and copy template there, not propagate to all image stores // and copy template there, not propagate to all image stores
// for that zone // for that zone
for (DataStore dstSecStore : dstSecStores) { for (DataStore dstSecStore : dstSecStores) {
TemplateDataStoreVO dstTmpltStore = this._tmplStoreDao.findByStoreTemplate(dstSecStore.getId(), tmpltId); TemplateDataStoreVO dstTmpltStore = _tmplStoreDao.findByStoreTemplate(dstSecStore.getId(), tmpltId);
if (dstTmpltStore != null && dstTmpltStore.getDownloadState() == Status.DOWNLOADED) { if (dstTmpltStore != null && dstTmpltStore.getDownloadState() == Status.DOWNLOADED) {
return true; // already downloaded on this image store return true; // already downloaded on this image store
} }
AsyncCallFuture<TemplateApiResult> future = this._tmpltSvr.copyTemplate(srcTemplate, dstSecStore); AsyncCallFuture<TemplateApiResult> future = _tmpltSvr.copyTemplate(srcTemplate, dstSecStore);
try { try {
TemplateApiResult result = future.get(); TemplateApiResult result = future.get();
if (result.isFailed()) { if (result.isFailed()) {
@ -775,7 +775,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
@Override @Override
public void evictTemplateFromStoragePool(VMTemplateStoragePoolVO templatePoolVO) { public void evictTemplateFromStoragePool(VMTemplateStoragePoolVO templatePoolVO) {
StoragePool pool = (StoragePool) this._dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId()); StoragePool pool = (StoragePool) _dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId());
VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId()); VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId());
if (s_logger.isDebugEnabled()) { if (s_logger.isDebugEnabled()) {
@ -974,7 +974,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
// for ISO, we need to consider whether to copy to cache storage or not if it is not on NFS, since our hypervisor resource always assumes that they are in NFS // for ISO, we need to consider whether to copy to cache storage or not if it is not on NFS, since our hypervisor resource always assumes that they are in NFS
@Override @Override
public TemplateInfo prepareIso(long isoId, long dcId){ public TemplateInfo prepareIso(long isoId, long dcId){
TemplateInfo tmplt = this._tmplFactory.getTemplate(isoId, DataStoreRole.Image, dcId); TemplateInfo tmplt = _tmplFactory.getTemplate(isoId, DataStoreRole.Image, dcId);
if (tmplt == null || tmplt.getFormat() != ImageFormat.ISO ) { if (tmplt == null || tmplt.getFormat() != ImageFormat.ISO ) {
s_logger.warn("ISO: " + isoId + " does not exist in vm_template table"); s_logger.warn("ISO: " + isoId + " does not exist in vm_template table");
return null; return null;
@ -995,7 +995,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
} }
private boolean attachISOToVM(long vmId, long isoId, boolean attach) { private boolean attachISOToVM(long vmId, long isoId, boolean attach) {
UserVmVO vm = this._userVmDao.findById(vmId); UserVmVO vm = _userVmDao.findById(vmId);
if (vm == null) { if (vm == null) {
return false; return false;
@ -1088,7 +1088,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
throw new InvalidParameterValueException("Unable to delete iso, as it's used by other vms"); throw new InvalidParameterValueException("Unable to delete iso, as it's used by other vms");
} }
if (zoneId != null && (this._dataStoreMgr.getImageStore(zoneId) == null)) { if (zoneId != null && (_dataStoreMgr.getImageStore(zoneId) == null)) {
throw new InvalidParameterValueException("Failed to find a secondary storage store in the specified zone."); throw new InvalidParameterValueException("Failed to find a secondary storage store in the specified zone.");
} }
TemplateAdapter adapter = getAdapter(template.getHypervisorType()); TemplateAdapter adapter = getAdapter(template.getHypervisorType());
@ -1339,7 +1339,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
VolumeVO volume = null; VolumeVO volume = null;
try { try {
TemplateInfo tmplInfo = this._tmplFactory.getTemplate(templateId, DataStoreRole.Image); TemplateInfo tmplInfo = _tmplFactory.getTemplate(templateId, DataStoreRole.Image);
long zoneId = 0; long zoneId = 0;
if (snapshotId != null) { if (snapshotId != null) {
snapshot = _snapshotDao.findById(snapshotId); snapshot = _snapshotDao.findById(snapshotId);
@ -1348,17 +1348,17 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
volume = _volumeDao.findById(volumeId); volume = _volumeDao.findById(volumeId);
zoneId = volume.getDataCenterId(); zoneId = volume.getDataCenterId();
} }
DataStore store = this._dataStoreMgr.getImageStore(zoneId); DataStore store = _dataStoreMgr.getImageStore(zoneId);
if (store == null) { if (store == null) {
throw new CloudRuntimeException("cannot find an image store for zone " + zoneId); throw new CloudRuntimeException("cannot find an image store for zone " + zoneId);
} }
AsyncCallFuture<TemplateApiResult> future = null; AsyncCallFuture<TemplateApiResult> future = null;
if (snapshotId != null) { if (snapshotId != null) {
SnapshotInfo snapInfo = this._snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Image); SnapshotInfo snapInfo = _snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Image);
future = this._tmpltSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store); future = _tmpltSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store);
} else if (volumeId != null) { } else if (volumeId != null) {
VolumeInfo volInfo = this._volFactory.getVolume(volumeId); VolumeInfo volInfo = _volFactory.getVolume(volumeId);
future = this._tmpltSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store); future = _tmpltSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store);
} else { } else {
throw new CloudRuntimeException("Creating private Template need to specify snapshotId or volumeId"); throw new CloudRuntimeException("Creating private Template need to specify snapshotId or volumeId");
} }
@ -1373,9 +1373,9 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
} }
VMTemplateZoneVO templateZone = new VMTemplateZoneVO(zoneId, templateId, new Date()); VMTemplateZoneVO templateZone = new VMTemplateZoneVO(zoneId, templateId, new Date());
this._tmpltZoneDao.persist(templateZone); _tmpltZoneDao.persist(templateZone);
privateTemplate = this._tmpltDao.findById(templateId); privateTemplate = _tmpltDao.findById(templateId);
if (snapshotId != null) { if (snapshotId != null) {
//getting the prent volume //getting the prent volume
long parentVolumeId=_snapshotDao.findById(snapshotId).getVolumeId(); long parentVolumeId=_snapshotDao.findById(snapshotId).getVolumeId();
@ -1392,7 +1392,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
_tmpltDao.update(privateTemplate.getId(), privateTemplate); _tmpltDao.update(privateTemplate.getId(), privateTemplate);
} }
} }
TemplateDataStoreVO srcTmpltStore = this._tmplStoreDao.findByStoreTemplate(store.getId(), templateId); TemplateDataStoreVO srcTmpltStore = _tmplStoreDao.findByStoreTemplate(store.getId(), templateId);
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, privateTemplate.getAccountId(), zoneId, UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, privateTemplate.getAccountId(), zoneId,
privateTemplate.getId(), privateTemplate.getName(), null, privateTemplate.getSourceTemplateId(), srcTmpltStore.getPhysicalSize(), privateTemplate.getSize()); privateTemplate.getId(), privateTemplate.getName(), null, privateTemplate.getSourceTemplateId(), srcTmpltStore.getPhysicalSize(), privateTemplate.getSize());
_usageEventDao.persist(usageEvent); _usageEventDao.persist(usageEvent);
@ -1419,11 +1419,11 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
// it up here to avoid // it up here to avoid
// some leftovers which will cause removing template from // some leftovers which will cause removing template from
// vm_template table fail. // vm_template table fail.
this._tmplStoreDao.deletePrimaryRecordsForTemplate(templateId); _tmplStoreDao.deletePrimaryRecordsForTemplate(templateId);
// Remove the template_zone_ref record // Remove the template_zone_ref record
this._tmpltZoneDao.deletePrimaryRecordsForTemplate(templateId); _tmpltZoneDao.deletePrimaryRecordsForTemplate(templateId);
// Remove the template record // Remove the template record
this._tmpltDao.expunge(templateId); _tmpltDao.expunge(templateId);
// decrement resource count // decrement resource count
if (accountId != null) { if (accountId != null) {
@ -1503,7 +1503,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
SnapshotVO snapshot = null; SnapshotVO snapshot = null;
VMTemplateVO privateTemplate = null; VMTemplateVO privateTemplate = null;
if (volumeId != null) { // create template from volume if (volumeId != null) { // create template from volume
volume = this._volumeDao.findById(volumeId); volume = _volumeDao.findById(volumeId);
if (volume == null) { if (volume == null) {
throw new InvalidParameterValueException("Failed to create private template record, unable to find volume " + volumeId); throw new InvalidParameterValueException("Failed to create private template record, unable to find volume " + volumeId);
} }
@ -1513,7 +1513,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
// If private template is created from Volume, check that the volume // If private template is created from Volume, check that the volume
// will not be active when the private template is // will not be active when the private template is
// created // created
if (!this._volumeMgr.volumeInactive(volume)) { if (!_volumeMgr.volumeInactive(volume)) {
String msg = "Unable to create private template for volume: " + volume.getName() String msg = "Unable to create private template for volume: " + volume.getName()
+ "; volume is attached to a non-stopped VM, please stop the VM first"; + "; volume is attached to a non-stopped VM, please stop the VM first";
if (s_logger.isInfoEnabled()) { if (s_logger.isInfoEnabled()) {
@ -1522,15 +1522,15 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
throw new CloudRuntimeException(msg); throw new CloudRuntimeException(msg);
} }
hyperType = this._volumeDao.getHypervisorType(volumeId); hyperType = _volumeDao.getHypervisorType(volumeId);
} else { // create template from snapshot } else { // create template from snapshot
snapshot = _snapshotDao.findById(snapshotId); snapshot = _snapshotDao.findById(snapshotId);
if (snapshot == null) { if (snapshot == null) {
throw new InvalidParameterValueException("Failed to create private template record, unable to find snapshot " + snapshotId); throw new InvalidParameterValueException("Failed to create private template record, unable to find snapshot " + snapshotId);
} }
volume = this._volumeDao.findById(snapshot.getVolumeId()); volume = _volumeDao.findById(snapshot.getVolumeId());
VolumeVO snapshotVolume = this._volumeDao.findByIdIncludingRemoved(snapshot.getVolumeId()); VolumeVO snapshotVolume = _volumeDao.findByIdIncludingRemoved(snapshot.getVolumeId());
// check permissions // check permissions
_accountMgr.checkAccess(caller, null, true, snapshot); _accountMgr.checkAccess(caller, null, true, snapshot);
@ -1560,13 +1560,13 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
featured = Boolean.FALSE; featured = Boolean.FALSE;
} }
Long guestOSId = cmd.getOsTypeId(); Long guestOSId = cmd.getOsTypeId();
GuestOSVO guestOS = this._guestOSDao.findById(guestOSId); GuestOSVO guestOS = _guestOSDao.findById(guestOSId);
if (guestOS == null) { if (guestOS == null) {
throw new InvalidParameterValueException("GuestOS with ID: " + guestOSId + " does not exist."); throw new InvalidParameterValueException("GuestOS with ID: " + guestOSId + " does not exist.");
} }
String uniqueName = Long.valueOf((userId == null) ? 1 : userId).toString() + UUID.nameUUIDFromBytes(name.getBytes()).toString(); String uniqueName = Long.valueOf((userId == null) ? 1 : userId).toString() + UUID.nameUUIDFromBytes(name.getBytes()).toString();
Long nextTemplateId = this._tmpltDao.getNextInSequence(Long.class, "id"); Long nextTemplateId = _tmpltDao.getNextInSequence(Long.class, "id");
String description = cmd.getDisplayText(); String description = cmd.getDisplayText();
boolean isExtractable = false; boolean isExtractable = false;
Long sourceTemplateId = null; Long sourceTemplateId = null;
@ -1602,11 +1602,11 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
} }
privateTemplate.setSourceTemplateId(sourceTemplateId); privateTemplate.setSourceTemplateId(sourceTemplateId);
VMTemplateVO template = this._tmpltDao.persist(privateTemplate); VMTemplateVO template = _tmpltDao.persist(privateTemplate);
// Increment the number of templates // Increment the number of templates
if (template != null) { if (template != null) {
if (cmd.getDetails() != null) { if (cmd.getDetails() != null) {
this._templateDetailsDao.persist(template.getId(), cmd.getDetails()); _templateDetailsDao.persist(template.getId(), cmd.getDetails());
} }
_resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.template); _resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.template);
@ -1624,19 +1624,19 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
@Override @Override
public Pair<String, String> getAbsoluteIsoPath(long templateId, long dataCenterId) { public Pair<String, String> getAbsoluteIsoPath(long templateId, long dataCenterId) {
TemplateDataStoreVO templateStoreRef = this._tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, dataCenterId, TemplateDataStoreVO templateStoreRef = _tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, dataCenterId,
VMTemplateStorageResourceAssoc.Status.DOWNLOADED); VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
if (templateStoreRef == null) { if (templateStoreRef == null) {
throw new CloudRuntimeException("Template " + templateId + " has not been completely downloaded to zone " + dataCenterId); throw new CloudRuntimeException("Template " + templateId + " has not been completely downloaded to zone " + dataCenterId);
} }
DataStore store = this._dataStoreMgr.getDataStore(templateStoreRef.getDataStoreId(), DataStoreRole.Image); DataStore store = _dataStoreMgr.getDataStore(templateStoreRef.getDataStoreId(), DataStoreRole.Image);
String isoPath = store.getUri() + "/" + templateStoreRef.getInstallPath(); String isoPath = store.getUri() + "/" + templateStoreRef.getInstallPath();
return new Pair<String, String>(isoPath, store.getUri()); return new Pair<String, String>(isoPath, store.getUri());
} }
@Override @Override
public String getSecondaryStorageURL(long zoneId) { public String getSecondaryStorageURL(long zoneId) {
DataStore secStore = this._dataStoreMgr.getImageStore(zoneId); DataStore secStore = _dataStoreMgr.getImageStore(zoneId);
if (secStore == null) { if (secStore == null) {
return null; return null;
} }
@ -1648,10 +1648,10 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
// just pick one is enough. // just pick one is enough.
@Override @Override
public DataStore getImageStore(long zoneId, long tmpltId) { public DataStore getImageStore(long zoneId, long tmpltId) {
TemplateDataStoreVO tmpltStore = this._tmplStoreDao.findByTemplateZoneDownloadStatus(tmpltId, zoneId, TemplateDataStoreVO tmpltStore = _tmplStoreDao.findByTemplateZoneDownloadStatus(tmpltId, zoneId,
VMTemplateStorageResourceAssoc.Status.DOWNLOADED); VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
if (tmpltStore != null) { if (tmpltStore != null) {
return this._dataStoreMgr.getDataStore(tmpltStore.getDataStoreId(), DataStoreRole.Image); return _dataStoreMgr.getDataStore(tmpltStore.getDataStoreId(), DataStoreRole.Image);
} }
return null; return null;
@ -1659,7 +1659,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
@Override @Override
public Long getTemplateSize(long templateId, long zoneId) { public Long getTemplateSize(long templateId, long zoneId) {
TemplateDataStoreVO templateStoreRef = this._tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, zoneId, TemplateDataStoreVO templateStoreRef = _tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, zoneId,
VMTemplateStorageResourceAssoc.Status.DOWNLOADED); VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
if (templateStoreRef == null) { if (templateStoreRef == null) {
throw new CloudRuntimeException("Template " + templateId + " has not been completely downloaded to zone " + zoneId); throw new CloudRuntimeException("Template " + templateId + " has not been completely downloaded to zone " + zoneId);
@ -1672,14 +1672,14 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
@Override @Override
public List<DataStore> getImageStoreByTemplate(long templateId, Long zoneId) { public List<DataStore> getImageStoreByTemplate(long templateId, Long zoneId) {
// find all eligible image stores for this zone scope // find all eligible image stores for this zone scope
List<DataStore> imageStores = this._dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId)); List<DataStore> imageStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId));
if (imageStores == null || imageStores.size() == 0) { if (imageStores == null || imageStores.size() == 0) {
return null; return null;
} }
List<DataStore> stores = new ArrayList<DataStore>(); List<DataStore> stores = new ArrayList<DataStore>();
for (DataStore store : imageStores) { for (DataStore store : imageStores) {
// check if the template is stored there // check if the template is stored there
List<TemplateDataStoreVO> storeTmpl = this._tmplStoreDao.listByTemplateStore(templateId, store.getId()); List<TemplateDataStoreVO> storeTmpl = _tmplStoreDao.listByTemplateStore(templateId, store.getId());
if (storeTmpl != null && storeTmpl.size() > 0) { if (storeTmpl != null && storeTmpl.size() > 0) {
stores.add(store); stores.add(store);
} }

View File

@ -66,6 +66,7 @@ import org.apache.cloudstack.engine.cloud.entity.api.VirtualMachineEntity;
import org.apache.cloudstack.engine.service.api.OrchestrationService; import org.apache.cloudstack.engine.service.api.OrchestrationService;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.cloudstack.storage.to.TemplateObjectTO;
@ -89,7 +90,6 @@ import com.cloud.alert.AlertManager;
import com.cloud.api.ApiDBUtils; import com.cloud.api.ApiDBUtils;
import com.cloud.api.query.dao.UserVmJoinDao; import com.cloud.api.query.dao.UserVmJoinDao;
import com.cloud.api.query.vo.UserVmJoinVO; import com.cloud.api.query.vo.UserVmJoinVO;
import com.cloud.async.AsyncJobManager;
import com.cloud.capacity.CapacityManager; import com.cloud.capacity.CapacityManager;
import com.cloud.configuration.Config; import com.cloud.configuration.Config;
import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.ConfigurationManager;

View File

@ -168,7 +168,7 @@ public class KeystoreTest extends TestCase {
vm.setObjectName("virtualmachine"); vm.setObjectName("virtualmachine");
*/ */
String result = ApiSerializerHelper.toSerializedStringOld(vm); String result = ApiSerializerHelper.toSerializedString(vm);
// String result = "org.apache.cloudstack.api.response.UserVmResponse/virtualmachine/{\"id\":{\"_tableName\":\"vm_instance\",\"_value\":3},\"name\":\"i-2-3-KY\",\"displayname\":\"i-2-3-KY\",\"account\":\"admin\",\"projectid\":{\"_tableName\":\"projects\"},\"domainid\":{\"_tableName\":\"domain\",\"_value\":1},\"domain\":\"ROOT\",\"created\":\"2011-11-02T21:54:07-0700\",\"state\":\"Running\",\"haenable\":false,\"groupid\":{\"_tableName\":\"instance_group\"},\"zoneid\":{\"_tableName\":\"data_center\",\"_value\":1},\"zonename\":\"KY\",\"hostid\":{\"_tableName\":\"host\",\"_value\":1},\"hostname\":\"xenserver-basic\",\"templateid\":{\"_tableName\":\"vm_template\",\"_value\":2},\"templatename\":\"CentOS 5.3(64-bit) no GUI (XenServer)\",\"templatedisplaytext\":\"CentOS 5.3(64-bit) no GUI (XenServer)\",\"passwordenabled\":false,\"isoid\":{\"_tableName\":\"vm_template\"},\"serviceofferingid\":{\"_tableName\":\"disk_offering\",\"_value\":7},\"serviceofferingname\":\"Small Instance\",\"cpunumber\":1,\"cpuspeed\":500,\"memory\":512,\"guestosid\":{\"_tableName\":\"guest_os\",\"_value\":12},\"rootdeviceid\":0,\"rootdevicetype\":\"NetworkFilesystem\",\"securitygroup\":[],\"jobid\":{\"_tableName\":\"async_job\"},\"nic\":[{\"id\":7,\"networkid\":200,\"netmask\":\"255.255.255.0\",\"gateway\":\"10.1.1.1\",\"ipaddress\":\"10.1.1.116\",\"isolationuri\":\"vlan://1699\",\"broadcasturi\":\"vlan://1699\",\"traffictype\":\"Guest\",\"type\":\"Virtual\",\"isdefault\":true,\"macaddress\":\"02:00:39:a7:00:01\"}],\"hypervisor\":\"XenServer\"}"; // String result = "org.apache.cloudstack.api.response.UserVmResponse/virtualmachine/{\"id\":{\"_tableName\":\"vm_instance\",\"_value\":3},\"name\":\"i-2-3-KY\",\"displayname\":\"i-2-3-KY\",\"account\":\"admin\",\"projectid\":{\"_tableName\":\"projects\"},\"domainid\":{\"_tableName\":\"domain\",\"_value\":1},\"domain\":\"ROOT\",\"created\":\"2011-11-02T21:54:07-0700\",\"state\":\"Running\",\"haenable\":false,\"groupid\":{\"_tableName\":\"instance_group\"},\"zoneid\":{\"_tableName\":\"data_center\",\"_value\":1},\"zonename\":\"KY\",\"hostid\":{\"_tableName\":\"host\",\"_value\":1},\"hostname\":\"xenserver-basic\",\"templateid\":{\"_tableName\":\"vm_template\",\"_value\":2},\"templatename\":\"CentOS 5.3(64-bit) no GUI (XenServer)\",\"templatedisplaytext\":\"CentOS 5.3(64-bit) no GUI (XenServer)\",\"passwordenabled\":false,\"isoid\":{\"_tableName\":\"vm_template\"},\"serviceofferingid\":{\"_tableName\":\"disk_offering\",\"_value\":7},\"serviceofferingname\":\"Small Instance\",\"cpunumber\":1,\"cpuspeed\":500,\"memory\":512,\"guestosid\":{\"_tableName\":\"guest_os\",\"_value\":12},\"rootdeviceid\":0,\"rootdevicetype\":\"NetworkFilesystem\",\"securitygroup\":[],\"jobid\":{\"_tableName\":\"async_job\"},\"nic\":[{\"id\":7,\"networkid\":200,\"netmask\":\"255.255.255.0\",\"gateway\":\"10.1.1.1\",\"ipaddress\":\"10.1.1.116\",\"isolationuri\":\"vlan://1699\",\"broadcasturi\":\"vlan://1699\",\"traffictype\":\"Guest\",\"type\":\"Virtual\",\"isdefault\":true,\"macaddress\":\"02:00:39:a7:00:01\"}],\"hypervisor\":\"XenServer\"}";
System.out.println(result); System.out.println(result);
//Object obj = ApiSerializerHelper.fromSerializedString(result); //Object obj = ApiSerializerHelper.fromSerializedString(result);
@ -177,7 +177,7 @@ public class KeystoreTest extends TestCase {
alert.setId("100"); alert.setId("100");
alert.setDescription("Hello"); alert.setDescription("Hello");
result = ApiSerializerHelper.toSerializedStringOld(alert); result = ApiSerializerHelper.toSerializedString(alert);
System.out.println(result); System.out.println(result);
ApiSerializerHelper.fromSerializedString(result); ApiSerializerHelper.fromSerializedString(result);
} }