mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-5160 add a map to specify the custom compute parameters in the deployvm api.
Signed-off-by: Jayapal <jayapal@apache.org>
This commit is contained in:
parent
f05063f377
commit
e5cfe94818
|
|
@ -202,7 +202,7 @@ public interface UserVmService {
|
|||
UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> securityGroupIdList,
|
||||
Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod,
|
||||
String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIp, Boolean displayVm, String keyboard,
|
||||
List<Long> affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootdisksize, String customId) throws InsufficientCapacityException,
|
||||
List<Long> affinityGroupIdList, Map<String, String> customParameter, String customId) throws InsufficientCapacityException,
|
||||
ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
|
||||
|
||||
/**
|
||||
|
|
@ -276,7 +276,7 @@ public interface UserVmService {
|
|||
UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList,
|
||||
List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
|
||||
HTTPMethod httpmethod, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard,
|
||||
List<Long> affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootdisksize, String customId) throws InsufficientCapacityException,
|
||||
List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId) throws InsufficientCapacityException,
|
||||
ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
|
||||
|
||||
/**
|
||||
|
|
@ -348,7 +348,7 @@ public interface UserVmService {
|
|||
UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList, Account owner,
|
||||
String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData,
|
||||
String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List<Long> affinityGroupIdList,
|
||||
Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootdkisksize, String customId)
|
||||
Map<String, String> customParameters, String customId)
|
||||
|
||||
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
|
||||
|
||||
|
|
|
|||
|
|
@ -230,29 +230,11 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd {
|
|||
description = "an optional field, whether to the display the vm to the end user or not.")
|
||||
private Boolean displayVm;
|
||||
|
||||
@Parameter(name = ApiConstants.CPU_SPEED,
|
||||
type = CommandType.INTEGER,
|
||||
since = "4.3",
|
||||
description = "optional field to specify the cpu speed when using dynamic compute offering.")
|
||||
private Integer cpuSpeed;
|
||||
|
||||
@Parameter(name = ApiConstants.MEMORY,
|
||||
type = CommandType.INTEGER,
|
||||
since = "4.3",
|
||||
description = "optional field to specify the memory when using dynamic compute offering")
|
||||
private Integer memory;
|
||||
|
||||
@Parameter(name = ApiConstants.CPU_NUMBER,
|
||||
type = CommandType.INTEGER,
|
||||
since = "4.3",
|
||||
description = "optional field to specify the number of cpu cores when using dynamic offering.")
|
||||
private Integer cpuNumber;
|
||||
|
||||
@Parameter(name = ApiConstants.ROOT_DISK_SIZE,
|
||||
type = CommandType.LONG,
|
||||
since = "4.3",
|
||||
description = "optional field to specify the number of cpu cores when using dynamic offering.")
|
||||
private Long rootdisksize;
|
||||
@Parameter(name = ApiConstants.CUSTOM_PARAMETERS,
|
||||
type = CommandType.MAP,
|
||||
since= "4.3",
|
||||
description = "used to specify the custom parameters.")
|
||||
private Map customParameters;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
|
|
@ -280,6 +262,21 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd {
|
|||
return domainId;
|
||||
}
|
||||
|
||||
public Map<String, String> getCustomParameters() {
|
||||
Map<String,String> customparameterMap = new HashMap<String, String>();
|
||||
if (customParameters != null && customParameters.size() !=0){
|
||||
Collection parameterCollection = customParameters.values();
|
||||
Iterator iter = parameterCollection.iterator();
|
||||
while (iter.hasNext()) {
|
||||
HashMap<String, String> value = (HashMap<String, String>) iter.next();
|
||||
for (String key : value.keySet()) {
|
||||
customparameterMap.put(key, value.get(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
return customparameterMap;
|
||||
}
|
||||
|
||||
public String getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
|
@ -292,21 +289,6 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd {
|
|||
return displayVm;
|
||||
}
|
||||
|
||||
public Integer getMemory() {
|
||||
return memory;
|
||||
}
|
||||
|
||||
public Integer getCpuSpeed() {
|
||||
return cpuSpeed;
|
||||
}
|
||||
|
||||
public Integer getCpuNumber() {
|
||||
return cpuNumber;
|
||||
}
|
||||
|
||||
public Long getRootdisksize() {
|
||||
return rootdisksize;
|
||||
}
|
||||
|
||||
public List<Long> getSecurityGroupIdList() {
|
||||
if (securityGroupNameList != null && securityGroupIdList != null) {
|
||||
|
|
@ -577,14 +559,14 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd {
|
|||
vm =
|
||||
_userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, getSecurityGroupIdList(), owner, name, displayName,
|
||||
diskOfferingId, size, group, getHypervisor(), getHttpMethod(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, displayVm, keyboard,
|
||||
getAffinityGroupIdList(), cpuSpeed, memory, cpuNumber, rootdisksize, getCustomId());
|
||||
getAffinityGroupIdList(), getCustomParameters(), getCustomId());
|
||||
}
|
||||
} else {
|
||||
if (zone.isSecurityGroupEnabled()) {
|
||||
vm =
|
||||
_userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, getNetworkIds(), getSecurityGroupIdList(), owner, name,
|
||||
displayName, diskOfferingId, size, group, getHypervisor(), getHttpMethod(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, displayVm,
|
||||
keyboard, getAffinityGroupIdList(), cpuSpeed, memory, cpuNumber, rootdisksize, getCustomId());
|
||||
keyboard, getAffinityGroupIdList(), getCustomParameters(), getCustomId());
|
||||
|
||||
} else {
|
||||
if (getSecurityGroupIdList() != null && !getSecurityGroupIdList().isEmpty()) {
|
||||
|
|
@ -593,7 +575,7 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd {
|
|||
vm =
|
||||
_userVmService.createAdvancedVirtualMachine(zone, serviceOffering, template, getNetworkIds(), owner, name, displayName, diskOfferingId, size,
|
||||
group, getHypervisor(), getHttpMethod(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, displayVm, keyboard, getAffinityGroupIdList(),
|
||||
cpuSpeed, memory, cpuNumber, rootdisksize, getCustomId());
|
||||
getCustomParameters(), getCustomId());
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2188,7 +2188,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
public UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template,
|
||||
List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
|
||||
HTTPMethod httpmethod, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard,
|
||||
List<Long> affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootDiskSize, String customId) throws InsufficientCapacityException,
|
||||
List<Long> affinityGroupIdList, Map<String, String> customParametes, String customId) throws InsufficientCapacityException,
|
||||
ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException {
|
||||
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
|
|
@ -2233,8 +2233,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
}
|
||||
|
||||
return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group,
|
||||
httpmethod, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, cpuSpeed, memory, cpuNumber,
|
||||
rootDiskSize, customId);
|
||||
httpmethod, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, customParametes, customId);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -2243,7 +2242,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList,
|
||||
List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
|
||||
HTTPMethod httpmethod, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard,
|
||||
List<Long> affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootDiskSize, String customId) throws InsufficientCapacityException,
|
||||
List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId) throws InsufficientCapacityException,
|
||||
ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException {
|
||||
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
|
|
@ -2342,8 +2341,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
}
|
||||
|
||||
return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group,
|
||||
httpmethod, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, cpuSpeed, memory, cpuNumber,
|
||||
rootDiskSize, customId);
|
||||
httpmethod, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, customParameters, customId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -2351,7 +2349,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
public UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList,
|
||||
Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod,
|
||||
String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayvm, String keyboard,
|
||||
List<Long> affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootDiskSize, String customId) throws InsufficientCapacityException,
|
||||
List<Long> affinityGroupIdList, Map<String, String> customParametrs, String customId) throws InsufficientCapacityException,
|
||||
ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException {
|
||||
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
|
|
@ -2440,7 +2438,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
}
|
||||
|
||||
return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, null, group, httpmethod,
|
||||
userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayvm, keyboard, affinityGroupIdList, cpuSpeed, memory, cpuNumber, rootDiskSize, customId);
|
||||
userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayvm, keyboard, affinityGroupIdList, customParametrs, customId);
|
||||
}
|
||||
|
||||
public void checkNameForRFCCompliance(String name) {
|
||||
|
|
@ -2454,7 +2452,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
protected UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate tmplt, String hostName, String displayName,
|
||||
Account owner, Long diskOfferingId, Long diskSize, List<NetworkVO> networkList, List<Long> securityGroupIdList, String group, HTTPMethod httpmethod,
|
||||
String userData, String sshKeyPair, HypervisorType hypervisor, Account caller, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps,
|
||||
Boolean isDisplayVmEnabled, String keyboard, List<Long> affinityGroupIdList, Integer cpuSpeed, Integer memory, Integer cpuNumber, Long rootDiskSize, String customId)
|
||||
Boolean isDisplayVmEnabled, String keyboard, List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId)
|
||||
throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, StorageUnavailableException, ResourceAllocationException {
|
||||
|
||||
_accountMgr.checkAccess(caller, null, true, owner);
|
||||
|
|
@ -2489,6 +2487,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
}
|
||||
|
||||
ServiceOfferingVO offering = _serviceOfferingDao.findById(serviceOffering.getId());
|
||||
if (offering.isDynamic()) {
|
||||
offering.setDynamicFlag(true);
|
||||
validateCustomParameters(offering, customParameters);
|
||||
offering = _offeringDao.getcomputeOffering(offering, customParameters);
|
||||
}
|
||||
// check if account/domain is with in resource limits to create a new vm
|
||||
boolean isIso = Storage.ImageFormat.ISO == template.getFormat();
|
||||
// For baremetal, size can be null
|
||||
|
|
@ -2500,11 +2503,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
if (diskOfferingId != null) {
|
||||
size += _diskOfferingDao.findById(diskOfferingId).getDiskSize();
|
||||
}
|
||||
if (!offering.isDynamic()) {
|
||||
resourceLimitCheck(owner, new Long(offering.getCpu()), new Long(offering.getRamSize()));
|
||||
} else {
|
||||
resourceLimitCheck(owner, new Long(cpuSpeed), new Long(memory));
|
||||
}
|
||||
resourceLimitCheck(owner, new Long(offering.getCpu()), new Long(offering.getRamSize()));
|
||||
|
||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, (isIso || diskOfferingId == null ? 1 : 2));
|
||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, size);
|
||||
|
||||
|
|
@ -2671,35 +2671,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
|
||||
long id = _vmDao.getNextInSequence(Long.class, "id");
|
||||
|
||||
List<UserVmDetailVO> details = new ArrayList<UserVmDetailVO>();
|
||||
if (offering.isDynamic()) {
|
||||
//insert the custom value of dynamic parameters
|
||||
if (offering.getCpu() == null) {
|
||||
if ((cpuNumber != null) && (cpuNumber <= 0)) {
|
||||
throw new InvalidParameterValueException("Invalid CPU number value, specify a value between 1 and 2147483647");
|
||||
}
|
||||
}
|
||||
|
||||
if (offering.getSpeed() == null) {
|
||||
if ((cpuSpeed != null) && (cpuSpeed <= 0)) {
|
||||
throw new InvalidParameterValueException("Invalid CPU speed value, specify a value between 1 and 2147483647");
|
||||
}
|
||||
}
|
||||
|
||||
if (offering.getRamSize() == null) {
|
||||
if ((memory != null) && (memory < 32)) {
|
||||
throw new InvalidParameterValueException("Invalid memory value, specify a value between 32 and 2147483647 MB");
|
||||
}
|
||||
}
|
||||
|
||||
details.add(new UserVmDetailVO(id, UsageEventVO.DynamicParameters.cpuNumber.toString(), cpuNumber.toString()));
|
||||
details.add(new UserVmDetailVO(id, UsageEventVO.DynamicParameters.cpuSpeed.toString(), cpuSpeed.toString()));
|
||||
details.add(new UserVmDetailVO(id, UsageEventVO.DynamicParameters.memory.toString(), memory.toString()));
|
||||
offering.setCpu(cpuNumber);
|
||||
offering.setRamSize(memory);
|
||||
offering.setSpeed(cpuSpeed);
|
||||
offering.setDynamicFlag(true);
|
||||
}
|
||||
if (hostName != null) {
|
||||
// Check is hostName is RFC compliant
|
||||
checkNameForRFCCompliance(hostName);
|
||||
|
|
@ -2770,7 +2742,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
|
||||
UserVmVO vm =
|
||||
commitUserVm(zone, template, hostName, displayName, owner, diskOfferingId, diskSize, userData, hypervisor, caller, isDisplayVmEnabled, keyboard, accountId,
|
||||
offering, isIso, sshPublicKey, networkNicMap, id, instanceName, uuidName, hypervisorType, rootDiskSize, details);
|
||||
offering, isIso, sshPublicKey, networkNicMap, id, instanceName, uuidName, hypervisorType, customParameters);
|
||||
|
||||
// Assign instance to the group
|
||||
try {
|
||||
|
|
@ -2801,7 +2773,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
final Long diskOfferingId, final Long diskSize, final String userData, final HypervisorType hypervisor, final Account caller, final Boolean isDisplayVmEnabled,
|
||||
final String keyboard, final long accountId, final ServiceOfferingVO offering, final boolean isIso, final String sshPublicKey,
|
||||
final LinkedHashMap<String, NicProfile> networkNicMap, final long id, final String instanceName, final String uuidName, final HypervisorType hypervisorType,
|
||||
final Long rootDiskSize, final List<UserVmDetailVO> vmdetails) throws InsufficientCapacityException {
|
||||
final Map<String, String> customParameters) throws InsufficientCapacityException {
|
||||
return Transaction.execute(new TransactionCallbackWithException<UserVmVO, InsufficientCapacityException>() {
|
||||
@Override
|
||||
public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCapacityException {
|
||||
|
|
@ -2820,6 +2792,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
if (isIso) {
|
||||
vm.setIsoId(template.getId());
|
||||
}
|
||||
Long rootDiskSize = null;
|
||||
if (customParameters.containsKey("rootdisksize")) {
|
||||
if (NumbersUtil.parseLong(customParameters.get("rootdisksize"), -1) <=0) {
|
||||
throw new InvalidParameterValueException("rootdisk size should be a non zero number.");
|
||||
}
|
||||
rootDiskSize = Long.parseLong(customParameters.get("rootDisksize"));
|
||||
customParameters.remove("rootdisksize");
|
||||
}
|
||||
|
||||
if (isDisplayVmEnabled != null) {
|
||||
if (!_accountMgr.isRootAdmin(caller.getType())) {
|
||||
|
|
@ -2864,9 +2844,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
}
|
||||
|
||||
_vmDao.persist(vm);
|
||||
if (vmdetails != null && vmdetails.size() > 0) {
|
||||
for (UserVmDetailVO detail : vmdetails) {
|
||||
vm.setDetail(detail.getName(), detail.getValue());
|
||||
if (customParameters != null && customParameters.size() > 0) {
|
||||
for (String key : customParameters.keySet()) {
|
||||
vm.setDetail(key, customParameters.get(key));
|
||||
}
|
||||
}
|
||||
_vmDao.saveDetails(vm);
|
||||
|
|
@ -2896,15 +2876,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
CallContext.current().setEventDetails("Vm Id: " + vm.getId());
|
||||
|
||||
if (!offering.isDynamic()) {
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(),
|
||||
vm.getHostName(), offering.getId(), template.getId(), hypervisorType.toString(),
|
||||
VirtualMachine.class.getName(), vm.getUuid());
|
||||
}
|
||||
else {
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), vm.getHostName(), offering.getId(),
|
||||
template.getId(), hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid());
|
||||
} else {
|
||||
HashMap<String, String> vmdetailsMap = new HashMap<String, String>();
|
||||
for (UserVmDetailVO vmdetail : vmdetails) {
|
||||
vmdetailsMap.put(vmdetail.getName(), vmdetail.getValue());
|
||||
}
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), vm.getHostName(), offering.getId(),
|
||||
template.getId(), hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid(), vmdetailsMap);
|
||||
template.getId(), hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid(), customParameters);
|
||||
}
|
||||
|
||||
//Update Resource Count for the given account
|
||||
|
|
|
|||
Loading…
Reference in New Issue