diff --git a/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/ClusterEntity.java b/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/ClusterEntity.java index d4d3a8cfac2..9497dd381f2 100755 --- a/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/ClusterEntity.java +++ b/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/ClusterEntity.java @@ -25,8 +25,6 @@ import com.cloud.org.Managed.ManagedState; public interface ClusterEntity extends DataCenterResourceEntity, OrganizationScope { - String getName(); - long getDataCenterId(); long getPodId(); @@ -39,5 +37,4 @@ public interface ClusterEntity extends DataCenterResourceEntity, OrganizationSco ManagedState getManagedState(); - } diff --git a/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceEntity.java b/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceEntity.java index 3e0b3f1c564..08175537ded 100755 --- a/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceEntity.java +++ b/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceEntity.java @@ -99,4 +99,6 @@ public interface DataCenterResourceEntity extends CloudStackEntity, StateObject< public void persist(); + + String getName(); } diff --git a/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/HostEntity.java b/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/HostEntity.java new file mode 100644 index 00000000000..9da196ecd9a --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/HostEntity.java @@ -0,0 +1,45 @@ +package org.apache.cloudstack.engine.datacenter.entity.api; + +import com.cloud.hypervisor.Hypervisor.HypervisorType; + +public interface HostEntity extends DataCenterResourceEntity { + + /** + * @return total amount of memory. + */ + Long getTotalMemory(); + + /** + * @return # of cores in a machine. Note two cpus with two cores each returns 4. + */ + Integer getCpus(); + + /** + * @return speed of each cpu in mhz. + */ + Long getSpeed(); + + /** + * @return the pod. + */ + Long getPodId(); + + /** + * @return availability zone. + */ + long getDataCenterId(); + + /** + * @return type of hypervisor + */ + HypervisorType getHypervisorType(); + + /** + * @return the mac address of the host. + */ + String getGuid(); + + Long getClusterId(); + +} + diff --git a/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/PodEntity.java b/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/PodEntity.java index 6eda5dd1ad9..fc870388227 100755 --- a/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/PodEntity.java +++ b/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/PodEntity.java @@ -36,8 +36,6 @@ public interface PodEntity extends DataCenterResourceEntity { long getDataCenterId(); - String getName(); - AllocationState getAllocationState(); boolean getExternalDhcp(); diff --git a/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/ZoneEntity.java b/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/ZoneEntity.java index c9ed9fbbe1b..ae789ead329 100755 --- a/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/ZoneEntity.java +++ b/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/ZoneEntity.java @@ -40,8 +40,4 @@ public interface ZoneEntity extends DataCenterResourceEntity { @Url(clazz=ProvisioningService.class, method="getPod", name="id", type=List.class) List listPodIds(); - - - String getName(); - } diff --git a/engine/api/src/org/apache/cloudstack/engine/service/api/ProvisioningService.java b/engine/api/src/org/apache/cloudstack/engine/service/api/ProvisioningService.java index e4517422061..8648f56bb9b 100755 --- a/engine/api/src/org/apache/cloudstack/engine/service/api/ProvisioningService.java +++ b/engine/api/src/org/apache/cloudstack/engine/service/api/ProvisioningService.java @@ -24,6 +24,7 @@ import java.util.Map; import javax.ws.rs.POST; import org.apache.cloudstack.engine.datacenter.entity.api.ClusterEntity; +import org.apache.cloudstack.engine.datacenter.entity.api.HostEntity; import org.apache.cloudstack.engine.datacenter.entity.api.PodEntity; import org.apache.cloudstack.engine.datacenter.entity.api.StorageEntity; import org.apache.cloudstack.engine.datacenter.entity.api.ZoneEntity; @@ -49,7 +50,7 @@ public interface ProvisioningService { ClusterEntity registerCluster(String clusterUuid, String name, String owner, List tags, Map details); - String registerHost(String name, List tags, Map details); + HostEntity registerHost(String uuid, String name, String owner, List tags, Map details); void deregisterStorage(String uuid); @@ -59,7 +60,7 @@ public interface ProvisioningService { void deregisterCluster(String uuid); - void deregisterHost(); + void deregisterHost(String uuid); void changeState(String type, String entity, Status state); diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceManager.java b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceManager.java index 11e24cb287b..f01db7e7cc2 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceManager.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceManager.java @@ -5,6 +5,7 @@ import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEnti import org.apache.cloudstack.engine.datacenter.entity.api.db.ClusterVO; import org.apache.cloudstack.engine.datacenter.entity.api.db.DataCenterVO; import org.apache.cloudstack.engine.datacenter.entity.api.db.HostPodVO; +import org.apache.cloudstack.engine.datacenter.entity.api.db.HostVO; import com.cloud.utils.fsm.NoTransitionException; @@ -26,4 +27,8 @@ public interface DataCenterResourceManager { ClusterVO loadCluster(String uuid); + HostVO loadHost(String uuid); + + void saveHost(HostVO hostVO); + } diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceManagerImpl.java b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceManagerImpl.java index 161d00e34b7..7a792c2c495 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceManagerImpl.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceManagerImpl.java @@ -7,8 +7,10 @@ import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEnti import org.apache.cloudstack.engine.datacenter.entity.api.db.ClusterVO; import org.apache.cloudstack.engine.datacenter.entity.api.db.DataCenterVO; import org.apache.cloudstack.engine.datacenter.entity.api.db.HostPodVO; +import org.apache.cloudstack.engine.datacenter.entity.api.db.HostVO; import org.apache.cloudstack.engine.datacenter.entity.api.db.dao.ClusterDao; import org.apache.cloudstack.engine.datacenter.entity.api.db.dao.DataCenterDao; +import org.apache.cloudstack.engine.datacenter.entity.api.db.dao.HostDao; import org.apache.cloudstack.engine.datacenter.entity.api.db.dao.HostPodDao; import org.springframework.stereotype.Component; @@ -29,6 +31,10 @@ public class DataCenterResourceManagerImpl implements DataCenterResourceManager @Inject ClusterDao _clusterDao; + @Inject + HostDao _hostDao; + + protected StateMachine2 _stateMachine = DataCenterResourceEntity.State.s_fsm; @Override @@ -49,12 +55,14 @@ public class DataCenterResourceManagerImpl implements DataCenterResourceManager @Override public boolean changeState(DataCenterResourceEntity entity, Event event) throws NoTransitionException { - if(entity instanceof ZoneEntity){ - return _stateMachine.transitTo((DataCenterResourceEntity)entity, event, null, _dataCenterDao); - }else if(entity instanceof PodEntity){ - return _stateMachine.transitTo((DataCenterResourceEntity)entity, event, null, _podDao); - }else if(entity instanceof ClusterEntity){ - return _stateMachine.transitTo((DataCenterResourceEntity)entity, event, null, _clusterDao); + if(entity instanceof ZoneEntity){ + return _stateMachine.transitTo(entity, event, null, _dataCenterDao); + }else if(entity instanceof PodEntity){ + return _stateMachine.transitTo(entity, event, null, _podDao); + }else if(entity instanceof ClusterEntity){ + return _stateMachine.transitTo(entity, event, null, _clusterDao); + }else if(entity instanceof HostEntity){ + return _stateMachine.transitTo(entity, event, null, _hostDao); } return false; @@ -88,4 +96,18 @@ public class DataCenterResourceManagerImpl implements DataCenterResourceManager _clusterDao.persist(cluster); } + @Override + public HostVO loadHost(String uuid) { + HostVO host = _hostDao.findByUUID(uuid); + if(host == null){ + throw new InvalidParameterValueException("Host does not exist"); + } + return host; + } + + @Override + public void saveHost(HostVO hostVO) { + _hostDao.persist(hostVO); + } + } diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/HostEntityImpl.java b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/HostEntityImpl.java new file mode 100644 index 00000000000..658a389a93d --- /dev/null +++ b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/HostEntityImpl.java @@ -0,0 +1,199 @@ +package org.apache.cloudstack.engine.datacenter.entity.api; + +import java.lang.reflect.Method; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity.State.Event; +import org.apache.cloudstack.engine.datacenter.entity.api.db.HostVO; + +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.utils.fsm.NoTransitionException; + +public class HostEntityImpl implements HostEntity { + + private DataCenterResourceManager manager; + + private HostVO hostVO; + + public HostEntityImpl(String uuid, DataCenterResourceManager manager) { + this.manager = manager; + hostVO = manager.loadHost(uuid); + } + + @Override + public boolean enable() { + try { + manager.changeState(this, Event.EnableRequest); + } catch (NoTransitionException e) { + return false; + } + return true; + } + + @Override + public boolean disable() { + try { + manager.changeState(this, Event.DisableRequest); + } catch (NoTransitionException e) { + return false; + } + return true; + } + + @Override + public boolean deactivate() { + try { + manager.changeState(this, Event.DeactivateRequest); + } catch (NoTransitionException e) { + return false; + } + return true; + } + + @Override + public boolean reactivate() { + try { + manager.changeState(this, Event.ActivatedRequest); + } catch (NoTransitionException e) { + return false; + } + return true; + } + + @Override + public State getState() { + return hostVO.getOrchestrationState(); + } + + @Override + public void persist() { + manager.saveHost(hostVO); + } + + @Override + public String getName() { + return hostVO.getName(); + } + + @Override + public String getUuid() { + return hostVO.getUuid(); + } + + @Override + public long getId() { + return hostVO.getId(); + } + + @Override + public String getCurrentState() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getDesiredState() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Date getCreatedTime() { + return hostVO.getCreated(); + } + + @Override + public Date getLastUpdatedTime() { + return hostVO.getLastUpdated(); + } + + @Override + public String getOwner() { + // TODO Auto-generated method stub + return hostVO.getOwner(); + } + + + public void setDetails(Map details) { + hostVO.setDetails(details); + } + + @Override + public Map getDetails() { + return hostVO.getDetails(); + } + + @Override + public void addDetail(String name, String value) { + hostVO.setDetail(name, value); + } + + @Override + public void delDetail(String name, String value) { + // TODO Auto-generated method stub + } + + @Override + public void updateDetail(String name, String value) { + // TODO Auto-generated method stub + + } + + @Override + public List getApplicableActions() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Long getTotalMemory() { + return hostVO.getTotalMemory(); + } + + @Override + public Integer getCpus() { + return hostVO.getCpus(); + } + + @Override + public Long getSpeed() { + return hostVO.getSpeed(); + } + + @Override + public Long getPodId() { + return hostVO.getPodId(); + } + + @Override + public long getDataCenterId() { + return hostVO.getDataCenterId(); + } + + @Override + public HypervisorType getHypervisorType() { + return hostVO.getHypervisorType(); + } + + @Override + public String getGuid() { + return hostVO.getGuid(); + } + + @Override + public Long getClusterId() { + return hostVO.getClusterId(); + } + + public void setOwner(String owner) { + hostVO.setOwner(owner); + } + + public void setName(String name) { + hostVO.setName(name); + } + + +} diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/HostVO.java b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/HostVO.java new file mode 100644 index 00000000000..210ed15f3ed --- /dev/null +++ b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/HostVO.java @@ -0,0 +1,777 @@ +// 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 org.apache.cloudstack.engine.datacenter.entity.api.db; + +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.DiscriminatorColumn; +import javax.persistence.DiscriminatorType; +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.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.Transient; + +import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity.State; +import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity.State.Event; + +import com.cloud.api.Identity; +import com.cloud.host.Host; +import com.cloud.host.Status; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.resource.ResourceState; +import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.db.GenericDao; +import com.cloud.utils.db.StateMachine; + +@Entity +@Table(name="host") +@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) +@DiscriminatorColumn(name="type", discriminatorType=DiscriminatorType.STRING, length=32) +public class HostVO implements Host, Identity { + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + private long id; + + @Column(name="disconnected") + @Temporal(value=TemporalType.TIMESTAMP) + private Date disconnectedOn; + + @Column(name="name", nullable=false) + private String name = null; + + /** + * Note: There is no setter for status because it has to be set in the dao code. + */ + @Column(name="status", nullable=false) + private Status status = null; + + @Column(name="type", updatable = true, nullable=false) + @Enumerated(value=EnumType.STRING) + private Type type; + + @Column(name="private_ip_address", nullable=false) + private String privateIpAddress; + + @Column(name="private_mac_address", nullable=false) + private String privateMacAddress; + + @Column(name="private_netmask", nullable=false) + private String privateNetmask; + + @Column(name="public_netmask") + private String publicNetmask; + + @Column(name="public_ip_address") + private String publicIpAddress; + + @Column(name="public_mac_address") + private String publicMacAddress; + + @Column(name="storage_ip_address") + private String storageIpAddress; + + @Column(name="cluster_id") + private Long clusterId; + + @Column(name="storage_netmask") + private String storageNetmask; + + @Column(name="storage_mac_address") + private String storageMacAddress; + + @Column(name="storage_ip_address_2") + private String storageIpAddressDeux; + + @Column(name="storage_netmask_2") + private String storageNetmaskDeux; + + @Column(name="storage_mac_address_2") + private String storageMacAddressDeux; + + @Column(name="hypervisor_type", updatable = true, nullable=false) + @Enumerated(value=EnumType.STRING) + private HypervisorType hypervisorType; + + @Column(name="proxy_port") + private Integer proxyPort; + + @Column(name="resource") + private String resource; + + @Column(name="fs_type") + private StoragePoolType fsType; + + @Column(name="available") + private boolean available = true; + + @Column(name="setup") + private boolean setup = false; + + @Column(name="resource_state", nullable=false) + @Enumerated(value=EnumType.STRING) + private ResourceState resourceState; + + @Column(name="hypervisor_version") + private String hypervisorVersion; + + @Column(name="update_count", updatable = true, nullable=false) + protected long updated; // This field should be updated everytime the state is updated. There's no set method in the vo object because it is done with in the dao code. + + @Column(name="uuid") + private String uuid; + + // This is a delayed load value. If the value is null, + // then this field has not been loaded yet. + // Call host dao to load it. + @Transient + Map details; + + // This is a delayed load value. If the value is null, + // then this field has not been loaded yet. + // Call host dao to load it. + @Transient + List hostTags; + + @Override + public String getStorageIpAddressDeux() { + return storageIpAddressDeux; + } + + public void setStorageIpAddressDeux(String deuxStorageIpAddress) { + this.storageIpAddressDeux = deuxStorageIpAddress; + } + + @Override + public String getStorageNetmaskDeux() { + return storageNetmaskDeux; + } + + @Override + public Long getClusterId() { + return clusterId; + } + + public void setClusterId(Long clusterId) { + this.clusterId = clusterId; + } + + public void setStorageNetmaskDeux(String deuxStorageNetmask) { + this.storageNetmaskDeux = deuxStorageNetmask; + } + + @Override + public String getStorageMacAddressDeux() { + return storageMacAddressDeux; + } + + public void setStorageMacAddressDeux(String duexStorageMacAddress) { + this.storageMacAddressDeux = duexStorageMacAddress; + } + + @Override + public String getPrivateMacAddress() { + return privateMacAddress; + } + + public void setPrivateMacAddress(String privateMacAddress) { + this.privateMacAddress = privateMacAddress; + } + + public boolean isAvailable() { + return available; + } + + public void setAvailable(boolean available) { + this.available = available; + } + + @Override + public String getPrivateNetmask() { + return privateNetmask; + } + + public void setPrivateNetmask(String privateNetmask) { + this.privateNetmask = privateNetmask; + } + + @Override + public String getPublicNetmask() { + return publicNetmask; + } + + public void setPublicNetmask(String publicNetmask) { + this.publicNetmask = publicNetmask; + } + + @Override + public String getPublicIpAddress() { + return publicIpAddress; + } + + public void setPublicIpAddress(String publicIpAddress) { + this.publicIpAddress = publicIpAddress; + } + + @Override + public String getPublicMacAddress() { + return publicMacAddress; + } + + public void setPublicMacAddress(String publicMacAddress) { + this.publicMacAddress = publicMacAddress; + } + + @Override + public String getStorageIpAddress() { + return storageIpAddress; + } + + public void setStorageIpAddress(String storageIpAddress) { + this.storageIpAddress = storageIpAddress; + } + + @Override + public String getStorageNetmask() { + return storageNetmask; + } + + public void setStorageNetmask(String storageNetmask) { + this.storageNetmask = storageNetmask; + } + + @Override + public String getStorageMacAddress() { + return storageMacAddress; + } + + public boolean isSetup() { + return setup; + } + + public void setSetup(boolean setup) { + this.setup = setup; + } + + public void setStorageMacAddress(String storageMacAddress) { + this.storageMacAddress = storageMacAddress; + } + + public String getResource() { + return resource; + } + + public void setResource(String resource) { + this.resource = resource; + } + + public Map getDetails() { + return details; + } + + public String getDetail(String name) { + assert (details != null) : "Did you forget to load the details?"; + + return details != null ? details.get(name) : null; + } + + public void setDetail(String name, String value) { + assert (details != null) : "Did you forget to load the details?"; + + details.put(name, value); + } + + public void setDetails(Map details) { + this.details = details; + } + + public List getHostTags() { + return hostTags; + } + + public void setHostTags(List hostTags) { + this.hostTags = hostTags; + } + + @Column(name="data_center_id", nullable=false) + private long dataCenterId; + + @Column(name="pod_id") + private Long podId; + + @Column(name="cpus") + private Integer cpus; + + @Column(name="url") + private String storageUrl; + + @Column(name="speed") + private Long speed; + + @Column(name="ram") + private long totalMemory; + + @Column(name="parent", nullable=false) + private String parent; + + @Column(name="guid", updatable=true, nullable=false) + private String guid; + + @Column(name="capabilities") + private String caps; + + @Column(name="total_size") + private Long totalSize; + + @Column(name="last_ping") + private long lastPinged; + + @Column(name="mgmt_server_id") + private Long managementServerId; + + @Column(name="dom0_memory") + private long dom0MinMemory; + + @Column(name="version") + private String version; + + @Column(name=GenericDao.CREATED_COLUMN) + private Date created; + + @Column(name=GenericDao.REMOVED_COLUMN) + private Date removed; + + //orchestration + @Column(name="owner") + private String owner = null; + + @Column(name="lastUpdated", updatable=true) + @Temporal(value=TemporalType.TIMESTAMP) + protected Date lastUpdated; + + /** + * Note that state is intentionally missing the setter. Any updates to + * the state machine needs to go through the DAO object because someone + * else could be updating it as well. + */ + @Enumerated(value=EnumType.STRING) + @StateMachine(state=State.class, event=Event.class) + @Column(name="state", updatable=true, nullable=false, length=32) + protected State state = null; + + + public HostVO(String guid) { + this.guid = guid; + this.status = Status.Creating; + this.totalMemory = 0; + this.dom0MinMemory = 0; + this.resourceState = ResourceState.Creating; + this.uuid = UUID.randomUUID().toString(); + this.state = State.Disabled; + } + + protected HostVO() { + this.uuid = UUID.randomUUID().toString(); + this.state = State.Disabled; + } + + public HostVO(long id, + String name, + Type type, + String privateIpAddress, + String privateNetmask, + String privateMacAddress, + String publicIpAddress, + String publicNetmask, + String publicMacAddress, + String storageIpAddress, + String storageNetmask, + String storageMacAddress, + String deuxStorageIpAddress, + String duxStorageNetmask, + String deuxStorageMacAddress, + String guid, + Status status, + String version, + String iqn, + Date disconnectedOn, + long dcId, + Long podId, + long serverId, + long ping, + String parent, + long totalSize, + StoragePoolType fsType) { + this(id, name, type, privateIpAddress, privateNetmask, privateMacAddress, publicIpAddress, publicNetmask, publicMacAddress, storageIpAddress, storageNetmask, storageMacAddress, guid, status, version, iqn, disconnectedOn, dcId, podId, serverId, ping, null, null, null, 0, null); + this.parent = parent; + this.totalSize = totalSize; + this.fsType = fsType; + this.uuid = UUID.randomUUID().toString(); + this.state = State.Disabled; + } + + public HostVO(long id, + String name, + Type type, + String privateIpAddress, + String privateNetmask, + String privateMacAddress, + String publicIpAddress, + String publicNetmask, + String publicMacAddress, + String storageIpAddress, + String storageNetmask, + String storageMacAddress, + String guid, + Status status, + String version, + String url, + Date disconnectedOn, + long dcId, + Long podId, + long serverId, + long ping, + Integer cpus, + Long speed, + Long totalMemory, + long dom0MinMemory, + String caps) { + this.id = id; + this.name = name; + this.status = status; + this.type = type; + this.privateIpAddress = privateIpAddress; + this.privateNetmask = privateNetmask; + this.privateMacAddress = privateMacAddress; + this.publicIpAddress = publicIpAddress; + this.publicNetmask = publicNetmask; + this.publicMacAddress = publicMacAddress; + this.storageIpAddress = storageIpAddress; + this.storageNetmask = storageNetmask; + this.storageMacAddress = storageMacAddress; + this.dataCenterId = dcId; + this.podId = podId; + this.cpus = cpus; + this.version = version; + this.speed = speed; + this.totalMemory = totalMemory != null ? totalMemory : 0; + this.guid = guid; + this.parent = null; + this.totalSize = null; + this.fsType = null; + this.managementServerId = serverId; + this.lastPinged = ping; + this.caps = caps; + this.disconnectedOn = disconnectedOn; + this.dom0MinMemory = dom0MinMemory; + this.storageUrl = url; + this.uuid = UUID.randomUUID().toString(); + this.state = State.Disabled; + } + + public void setPodId(Long podId) { + + this.podId = podId; + } + + public void setDataCenterId(long dcId) { + this.dataCenterId = dcId; + } + + public void setVersion(String version) { + this.version = version; + } + + public void setStorageUrl(String url) { + this.storageUrl = url; + } + + public void setDisconnectedOn(Date disconnectedOn) { + this.disconnectedOn = disconnectedOn; + } + + public String getStorageUrl() { + return storageUrl; + } + + public void setName(String name) { + this.name = name; + } + + public void setPrivateIpAddress(String ipAddress) { + this.privateIpAddress = ipAddress; + } + + public void setCpus(Integer cpus) { + this.cpus = cpus; + } + + public void setSpeed(Long speed) { + this.speed = speed; + } + + public void setTotalMemory(long totalMemory) { + this.totalMemory = totalMemory; + } + + public void setParent(String parent) { + this.parent = parent; + } + + public void setCaps(String caps) { + this.caps = caps; + } + + public void setTotalSize(Long totalSize) { + this.totalSize = totalSize; + } + + public void setLastPinged(long lastPinged) { + this.lastPinged = lastPinged; + } + + public void setManagementServerId(Long managementServerId) { + this.managementServerId = managementServerId; + } + + @Override + public long getLastPinged() { + return lastPinged; + } + + @Override + public String getParent() { + return parent; + } + + @Override + public long getTotalSize() { + return totalSize; + } + + @Override + public String getCapabilities() { + return caps; + } + + @Override + public Date getCreated() { + return created; + } + + @Override + public Date getRemoved() { + return removed; + } + + @Override + public String getVersion() { + return version; + } + + public void setType(Type type) { + this.type = type; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getName() { + return name; + } + + @Override + public Status getStatus() { + return status; + } + + @Override + public long getDataCenterId() { + return dataCenterId; + } + + @Override + public Long getPodId() { + return podId; + } + + @Override + public Long getManagementServerId() { + return managementServerId; + } + + @Override + public Date getDisconnectedOn() { + return disconnectedOn; + } + + @Override + public String getPrivateIpAddress() { + return privateIpAddress; + } + + @Override + public String getGuid() { + return guid; + } + + public void setGuid(String guid) { + this.guid = guid; + } + + @Override + public Integer getCpus() { + return cpus; + } + + @Override + public Long getSpeed() { + return speed; + } + + @Override + public Long getTotalMemory() { + return totalMemory; + } + + @Override + public Integer getProxyPort() { + return proxyPort; + } + + public void setProxyPort(Integer port) { + proxyPort = port; + } + + public StoragePoolType getFsType() { + return fsType; + } + + @Override + public Type getType() { + return type; + } + + @Override + public int hashCode() { + return NumbersUtil.hash(id); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof HostVO) { + return ((HostVO)obj).getId() == this.getId(); + } else { + return false; + } + } + + @Override + public String toString() { + return new StringBuilder("Host[").append("-").append(id).append("-").append(type).append("]").toString(); + } + + public void setHypervisorType(HypervisorType hypervisorType) { + this.hypervisorType = hypervisorType; + } + + @Override + public HypervisorType getHypervisorType() { + return hypervisorType; + } + + public void setHypervisorVersion(String hypervisorVersion) { + this.hypervisorVersion = hypervisorVersion; + } + + @Override + public String getHypervisorVersion() { + return hypervisorVersion; + } + + @Override + @Transient + public Status getState() { + return status; + } + + @Override + public ResourceState getResourceState() { + return resourceState; + } + + public void setResourceState(ResourceState state) { + resourceState = state; + } + + @Override + public boolean isInMaintenanceStates() { + return (getResourceState() == ResourceState.Maintenance || getResourceState() == ResourceState.ErrorInMaintenance + || getResourceState() == ResourceState.PrepareForMaintenance); + } + + public long getUpdated() { + return updated; + } + + public long incrUpdated() { + updated++; + return updated; + } + + @Override + public String getUuid() { + return this.uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + + public Date getLastUpdated() { + return lastUpdated; + } + + public State getOrchestrationState() { + return state; + } +} diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDao.java b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDao.java new file mode 100644 index 00000000000..e3437afbca5 --- /dev/null +++ b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDao.java @@ -0,0 +1,87 @@ +// 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 org.apache.cloudstack.engine.datacenter.entity.api.db.dao; + +import java.util.Date; +import java.util.List; + +import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity; +import org.apache.cloudstack.engine.datacenter.entity.api.db.HostVO; + +import com.cloud.host.Host; +import com.cloud.host.Host.Type; +import com.cloud.host.Status; +import com.cloud.info.RunningHostCountInfo; +import com.cloud.resource.ResourceState; +import com.cloud.utils.db.GenericDao; +import com.cloud.utils.fsm.StateDao; + +/** + * Data Access Object for server + * + */ +public interface HostDao extends GenericDao, StateDao { + long countBy(long clusterId, ResourceState... states); + + /** + * Mark all hosts associated with a certain management server + * as disconnected. + * + * @param msId management server id. + */ + void markHostsAsDisconnected(long msId, long lastPing); + + List findLostHosts(long timeout); + + List findAndUpdateDirectAgentToLoad(long lastPingSecondsAfter, Long limit, long managementServerId); + + List getRunningHostCounts(Date cutTime); + + long getNextSequence(long hostId); + + void loadDetails(HostVO host); + + void saveDetails(HostVO host); + + void loadHostTags(HostVO host); + + List listByHostTag(Host.Type type, Long clusterId, Long podId, long dcId, String hostTag); + + long countRoutingHostsByDataCenter(long dcId); + + List findAndUpdateApplianceToLoad(long lastPingSecondsAfter, long managementServerId); + + boolean updateResourceState(ResourceState oldState, ResourceState.Event event, ResourceState newState, Host vo); + + HostVO findByGuid(String guid); + + HostVO findByTypeNameAndZoneId(long zoneId, String name, Host.Type type); + List findHypervisorHostInCluster(long clusterId); + + + /** + * @param type + * @param clusterId + * @param podId + * @param dcId + * @param haTag TODO + * @return + */ + List listAllUpAndEnabledNonHAHosts(Type type, Long clusterId, Long podId, long dcId, String haTag); + + HostVO findByUUID(String uuid); +} diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDaoImpl.java b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDaoImpl.java new file mode 100644 index 00000000000..ede5d8cef12 --- /dev/null +++ b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDaoImpl.java @@ -0,0 +1,823 @@ +// 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 org.apache.cloudstack.engine.datacenter.entity.api.db.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.Map; +import java.util.TimeZone; + +import javax.ejb.Local; +import javax.persistence.TableGenerator; + +import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity; +import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity.State; +import org.apache.cloudstack.engine.datacenter.entity.api.db.ClusterVO; +import org.apache.cloudstack.engine.datacenter.entity.api.db.DataCenterVO; +import org.apache.cloudstack.engine.datacenter.entity.api.db.HostVO; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.host.Host; +import com.cloud.host.Host.Type; +import com.cloud.host.HostTagVO; + +import com.cloud.host.Status; +import com.cloud.host.Status.Event; +import com.cloud.info.RunningHostCountInfo; +import com.cloud.org.Managed; +import com.cloud.resource.ResourceState; +import com.cloud.utils.DateUtil; +import com.cloud.utils.component.ComponentLocator; +import com.cloud.utils.db.Attribute; +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.JoinBuilder; +import com.cloud.utils.db.JoinBuilder.JoinType; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Func; +import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.UpdateBuilder; +import com.cloud.utils.exception.CloudRuntimeException; + + +@Local(value = { HostDao.class }) +@DB(txn = false) +@TableGenerator(name = "host_req_sq", table = "op_host", pkColumnName = "id", valueColumnName = "sequence", allocationSize = 1) +public class HostDaoImpl extends GenericDaoBase implements HostDao { + private static final Logger s_logger = Logger.getLogger(HostDaoImpl.class); + private static final Logger status_logger = Logger.getLogger(Status.class); + private static final Logger state_logger = Logger.getLogger(ResourceState.class); + + protected final SearchBuilder TypePodDcStatusSearch; + + protected final SearchBuilder IdStatusSearch; + protected final SearchBuilder TypeDcSearch; + protected final SearchBuilder TypeDcStatusSearch; + protected final SearchBuilder TypeClusterStatusSearch; + protected final SearchBuilder MsStatusSearch; + protected final SearchBuilder DcPrivateIpAddressSearch; + protected final SearchBuilder DcStorageIpAddressSearch; + + protected final SearchBuilder GuidSearch; + protected final SearchBuilder DcSearch; + protected final SearchBuilder PodSearch; + protected final SearchBuilder TypeSearch; + protected final SearchBuilder StatusSearch; + protected final SearchBuilder ResourceStateSearch; + protected final SearchBuilder NameLikeSearch; + protected final SearchBuilder NameSearch; + protected final SearchBuilder SequenceSearch; + protected final SearchBuilder DirectlyConnectedSearch; + protected final SearchBuilder UnmanagedDirectConnectSearch; + protected final SearchBuilder UnmanagedApplianceSearch; + protected final SearchBuilder MaintenanceCountSearch; + protected final SearchBuilder ClusterStatusSearch; + protected final SearchBuilder TypeNameZoneSearch; + protected final SearchBuilder AvailHypevisorInZone; + + protected final SearchBuilder DirectConnectSearch; + protected final SearchBuilder ManagedDirectConnectSearch; + protected final SearchBuilder ManagedRoutingServersSearch; + protected final SearchBuilder SecondaryStorageVMSearch; + protected SearchBuilder StateChangeSearch; + + protected SearchBuilder UUIDSearch; + + protected final GenericSearchBuilder HostsInStatusSearch; + protected final GenericSearchBuilder CountRoutingByDc; + protected final SearchBuilder RoutingSearch; + + protected final Attribute _statusAttr; + protected final Attribute _resourceStateAttr; + protected final Attribute _msIdAttr; + protected final Attribute _pingTimeAttr; + + protected final HostDetailsDaoImpl _detailsDao = ComponentLocator.inject(HostDetailsDaoImpl.class); + protected final HostTagsDaoImpl _hostTagsDao = ComponentLocator.inject(HostTagsDaoImpl.class); + protected final ClusterDaoImpl _clusterDao = ComponentLocator.inject(ClusterDaoImpl.class); + + + public HostDaoImpl() { + + MaintenanceCountSearch = createSearchBuilder(); + MaintenanceCountSearch.and("cluster", MaintenanceCountSearch.entity().getClusterId(), SearchCriteria.Op.EQ); + MaintenanceCountSearch.and("resourceState", MaintenanceCountSearch.entity().getResourceState(), SearchCriteria.Op.IN); + MaintenanceCountSearch.done(); + + TypePodDcStatusSearch = createSearchBuilder(); + HostVO entity = TypePodDcStatusSearch.entity(); + TypePodDcStatusSearch.and("type", entity.getType(), SearchCriteria.Op.EQ); + TypePodDcStatusSearch.and("pod", entity.getPodId(), SearchCriteria.Op.EQ); + TypePodDcStatusSearch.and("dc", entity.getDataCenterId(), SearchCriteria.Op.EQ); + TypePodDcStatusSearch.and("cluster", entity.getClusterId(), SearchCriteria.Op.EQ); + TypePodDcStatusSearch.and("status", entity.getStatus(), SearchCriteria.Op.EQ); + TypePodDcStatusSearch.and("resourceState", entity.getResourceState(), SearchCriteria.Op.EQ); + TypePodDcStatusSearch.done(); + + MsStatusSearch = createSearchBuilder(); + MsStatusSearch.and("ms", MsStatusSearch.entity().getManagementServerId(), SearchCriteria.Op.EQ); + MsStatusSearch.and("type", MsStatusSearch.entity().getType(), SearchCriteria.Op.EQ); + MsStatusSearch.and("resourceState", MsStatusSearch.entity().getResourceState(), SearchCriteria.Op.NIN); + MsStatusSearch.done(); + + TypeDcSearch = createSearchBuilder(); + TypeDcSearch.and("type", TypeDcSearch.entity().getType(), SearchCriteria.Op.EQ); + TypeDcSearch.and("dc", TypeDcSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + TypeDcSearch.done(); + + SecondaryStorageVMSearch = createSearchBuilder(); + SecondaryStorageVMSearch.and("type", SecondaryStorageVMSearch.entity().getType(), SearchCriteria.Op.EQ); + SecondaryStorageVMSearch.and("dc", SecondaryStorageVMSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + SecondaryStorageVMSearch.and("status", SecondaryStorageVMSearch.entity().getStatus(), SearchCriteria.Op.EQ); + SecondaryStorageVMSearch.done(); + + TypeDcStatusSearch = createSearchBuilder(); + TypeDcStatusSearch.and("type", TypeDcStatusSearch.entity().getType(), SearchCriteria.Op.EQ); + TypeDcStatusSearch.and("dc", TypeDcStatusSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + TypeDcStatusSearch.and("status", TypeDcStatusSearch.entity().getStatus(), SearchCriteria.Op.EQ); + TypeDcStatusSearch.and("resourceState", TypeDcStatusSearch.entity().getResourceState(), SearchCriteria.Op.EQ); + TypeDcStatusSearch.done(); + + TypeClusterStatusSearch = createSearchBuilder(); + TypeClusterStatusSearch.and("type", TypeClusterStatusSearch.entity().getType(), SearchCriteria.Op.EQ); + TypeClusterStatusSearch.and("cluster", TypeClusterStatusSearch.entity().getClusterId(), SearchCriteria.Op.EQ); + TypeClusterStatusSearch.and("status", TypeClusterStatusSearch.entity().getStatus(), SearchCriteria.Op.EQ); + TypeClusterStatusSearch.and("resourceState", TypeClusterStatusSearch.entity().getResourceState(), SearchCriteria.Op.EQ); + TypeClusterStatusSearch.done(); + + IdStatusSearch = createSearchBuilder(); + IdStatusSearch.and("id", IdStatusSearch.entity().getId(), SearchCriteria.Op.EQ); + IdStatusSearch.and("states", IdStatusSearch.entity().getStatus(), SearchCriteria.Op.IN); + IdStatusSearch.done(); + + DcPrivateIpAddressSearch = createSearchBuilder(); + DcPrivateIpAddressSearch.and("privateIpAddress", DcPrivateIpAddressSearch.entity().getPrivateIpAddress(), SearchCriteria.Op.EQ); + DcPrivateIpAddressSearch.and("dc", DcPrivateIpAddressSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + DcPrivateIpAddressSearch.done(); + + DcStorageIpAddressSearch = createSearchBuilder(); + DcStorageIpAddressSearch.and("storageIpAddress", DcStorageIpAddressSearch.entity().getStorageIpAddress(), SearchCriteria.Op.EQ); + DcStorageIpAddressSearch.and("dc", DcStorageIpAddressSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + DcStorageIpAddressSearch.done(); + + GuidSearch = createSearchBuilder(); + GuidSearch.and("guid", GuidSearch.entity().getGuid(), SearchCriteria.Op.EQ); + GuidSearch.done(); + + DcSearch = createSearchBuilder(); + DcSearch.and("dc", DcSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + DcSearch.done(); + + ClusterStatusSearch = createSearchBuilder(); + ClusterStatusSearch.and("cluster", ClusterStatusSearch.entity().getClusterId(), SearchCriteria.Op.EQ); + ClusterStatusSearch.and("status", ClusterStatusSearch.entity().getStatus(), SearchCriteria.Op.EQ); + ClusterStatusSearch.done(); + + TypeNameZoneSearch = createSearchBuilder(); + TypeNameZoneSearch.and("name", TypeNameZoneSearch.entity().getName(), SearchCriteria.Op.EQ); + TypeNameZoneSearch.and("type", TypeNameZoneSearch.entity().getType(), SearchCriteria.Op.EQ); + TypeNameZoneSearch.and("zoneId", TypeNameZoneSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + TypeNameZoneSearch.done(); + + PodSearch = createSearchBuilder(); + PodSearch.and("pod", PodSearch.entity().getPodId(), SearchCriteria.Op.EQ); + PodSearch.done(); + + TypeSearch = createSearchBuilder(); + TypeSearch.and("type", TypeSearch.entity().getType(), SearchCriteria.Op.EQ); + TypeSearch.done(); + + StatusSearch = createSearchBuilder(); + StatusSearch.and("status", StatusSearch.entity().getStatus(), SearchCriteria.Op.IN); + StatusSearch.done(); + + ResourceStateSearch = createSearchBuilder(); + ResourceStateSearch.and("resourceState", ResourceStateSearch.entity().getResourceState(), SearchCriteria.Op.IN); + ResourceStateSearch.done(); + + NameLikeSearch = createSearchBuilder(); + NameLikeSearch.and("name", NameLikeSearch.entity().getName(), SearchCriteria.Op.LIKE); + NameLikeSearch.done(); + + NameSearch = createSearchBuilder(); + NameSearch.and("name", NameSearch.entity().getName(), SearchCriteria.Op.EQ); + NameSearch.done(); + + SequenceSearch = createSearchBuilder(); + SequenceSearch.and("id", SequenceSearch.entity().getId(), SearchCriteria.Op.EQ); + // SequenceSearch.addRetrieve("sequence", SequenceSearch.entity().getSequence()); + SequenceSearch.done(); + + DirectlyConnectedSearch = createSearchBuilder(); + DirectlyConnectedSearch.and("resource", DirectlyConnectedSearch.entity().getResource(), SearchCriteria.Op.NNULL); + DirectlyConnectedSearch.and("ms", DirectlyConnectedSearch.entity().getManagementServerId(), SearchCriteria.Op.EQ); + DirectlyConnectedSearch.and("statuses", DirectlyConnectedSearch.entity().getStatus(), SearchCriteria.Op.EQ); + DirectlyConnectedSearch.and("resourceState", DirectlyConnectedSearch.entity().getResourceState(), SearchCriteria.Op.NOTIN); + DirectlyConnectedSearch.done(); + + UnmanagedDirectConnectSearch = createSearchBuilder(); + UnmanagedDirectConnectSearch.and("resource", UnmanagedDirectConnectSearch.entity().getResource(), SearchCriteria.Op.NNULL); + UnmanagedDirectConnectSearch.and("server", UnmanagedDirectConnectSearch.entity().getManagementServerId(), SearchCriteria.Op.NULL); + UnmanagedDirectConnectSearch.and("lastPinged", UnmanagedDirectConnectSearch.entity().getLastPinged(), SearchCriteria.Op.LTEQ); + UnmanagedDirectConnectSearch.and("resourceStates", UnmanagedDirectConnectSearch.entity().getResourceState(), SearchCriteria.Op.NIN); + /* + * UnmanagedDirectConnectSearch.op(SearchCriteria.Op.OR, "managementServerId", + * UnmanagedDirectConnectSearch.entity().getManagementServerId(), SearchCriteria.Op.EQ); + * UnmanagedDirectConnectSearch.and("lastPinged", UnmanagedDirectConnectSearch.entity().getLastPinged(), + * SearchCriteria.Op.LTEQ); UnmanagedDirectConnectSearch.cp(); UnmanagedDirectConnectSearch.cp(); + */ + + DirectConnectSearch = createSearchBuilder(); + DirectConnectSearch.and("resource", DirectConnectSearch.entity().getResource(), SearchCriteria.Op.NNULL); + DirectConnectSearch.and("id", DirectConnectSearch.entity().getId(), SearchCriteria.Op.EQ); + DirectConnectSearch.and().op("nullserver", DirectConnectSearch.entity().getManagementServerId(), SearchCriteria.Op.NULL); + DirectConnectSearch.or("server", DirectConnectSearch.entity().getManagementServerId(), SearchCriteria.Op.EQ); + DirectConnectSearch.cp(); + DirectConnectSearch.done(); + + UnmanagedApplianceSearch = createSearchBuilder(); + UnmanagedApplianceSearch.and("resource", UnmanagedApplianceSearch.entity().getResource(), SearchCriteria.Op.NNULL); + UnmanagedApplianceSearch.and("server", UnmanagedApplianceSearch.entity().getManagementServerId(), SearchCriteria.Op.NULL); + UnmanagedApplianceSearch.and("types", UnmanagedApplianceSearch.entity().getType(), SearchCriteria.Op.IN); + UnmanagedApplianceSearch.and("lastPinged", UnmanagedApplianceSearch.entity().getLastPinged(), SearchCriteria.Op.LTEQ); + UnmanagedApplianceSearch.done(); + + AvailHypevisorInZone = createSearchBuilder(); + AvailHypevisorInZone.and("zoneId", AvailHypevisorInZone.entity().getDataCenterId(), SearchCriteria.Op.EQ); + AvailHypevisorInZone.and("hostId", AvailHypevisorInZone.entity().getId(), SearchCriteria.Op.NEQ); + AvailHypevisorInZone.and("type", AvailHypevisorInZone.entity().getType(), SearchCriteria.Op.EQ); + AvailHypevisorInZone.groupBy(AvailHypevisorInZone.entity().getHypervisorType()); + AvailHypevisorInZone.done(); + + HostsInStatusSearch = createSearchBuilder(Long.class); + HostsInStatusSearch.selectField(HostsInStatusSearch.entity().getId()); + HostsInStatusSearch.and("dc", HostsInStatusSearch.entity().getDataCenterId(), Op.EQ); + HostsInStatusSearch.and("pod", HostsInStatusSearch.entity().getPodId(), Op.EQ); + HostsInStatusSearch.and("cluster", HostsInStatusSearch.entity().getClusterId(), Op.EQ); + HostsInStatusSearch.and("type", HostsInStatusSearch.entity().getType(), Op.EQ); + HostsInStatusSearch.and("statuses", HostsInStatusSearch.entity().getStatus(), Op.IN); + HostsInStatusSearch.done(); + + CountRoutingByDc = createSearchBuilder(Long.class); + CountRoutingByDc.select(null, Func.COUNT, null); + CountRoutingByDc.and("dc", CountRoutingByDc.entity().getDataCenterId(), SearchCriteria.Op.EQ); + CountRoutingByDc.and("type", CountRoutingByDc.entity().getType(), SearchCriteria.Op.EQ); + CountRoutingByDc.and("status", CountRoutingByDc.entity().getStatus(), SearchCriteria.Op.EQ); + + CountRoutingByDc.done(); + + ManagedDirectConnectSearch = createSearchBuilder(); + ManagedDirectConnectSearch.and("resource", ManagedDirectConnectSearch.entity().getResource(), SearchCriteria.Op.NNULL); + ManagedDirectConnectSearch.and("server", ManagedDirectConnectSearch.entity().getManagementServerId(), SearchCriteria.Op.NULL); + ManagedDirectConnectSearch.done(); + + ManagedRoutingServersSearch = createSearchBuilder(); + ManagedRoutingServersSearch.and("server", ManagedRoutingServersSearch.entity().getManagementServerId(), SearchCriteria.Op.NNULL); + ManagedRoutingServersSearch.and("type", ManagedRoutingServersSearch.entity().getType(), SearchCriteria.Op.EQ); + ManagedRoutingServersSearch.done(); + + RoutingSearch = createSearchBuilder(); + RoutingSearch.and("type", RoutingSearch.entity().getType(), SearchCriteria.Op.EQ); + RoutingSearch.done(); + + _statusAttr = _allAttributes.get("status"); + _msIdAttr = _allAttributes.get("managementServerId"); + _pingTimeAttr = _allAttributes.get("lastPinged"); + _resourceStateAttr = _allAttributes.get("resourceState"); + + assert (_statusAttr != null && _msIdAttr != null && _pingTimeAttr != null) : "Couldn't find one of these attributes"; + + UUIDSearch = createSearchBuilder(); + UUIDSearch.and("uuid", UUIDSearch.entity().getUuid(), SearchCriteria.Op.EQ); + UUIDSearch.done(); + + StateChangeSearch = createSearchBuilder(); + StateChangeSearch.and("id", StateChangeSearch.entity().getId(), SearchCriteria.Op.EQ); + StateChangeSearch.and("state", StateChangeSearch.entity().getState(), SearchCriteria.Op.EQ); + StateChangeSearch.done(); + } + + @Override + public long countBy(long clusterId, ResourceState... states) { + SearchCriteria sc = MaintenanceCountSearch.create(); + + sc.setParameters("resourceState", (Object[]) states); + sc.setParameters("cluster", clusterId); + + List hosts = listBy(sc); + return hosts.size(); + } + + + @Override + public HostVO findByGuid(String guid) { + SearchCriteria sc = GuidSearch.create("guid", guid); + return findOneBy(sc); + } + + @Override @DB + public List findAndUpdateDirectAgentToLoad(long lastPingSecondsAfter, Long limit, long managementServerId) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + SearchCriteria sc = UnmanagedDirectConnectSearch.create(); + sc.setParameters("lastPinged", lastPingSecondsAfter); + //sc.setParameters("resourceStates", ResourceState.ErrorInMaintenance, ResourceState.Maintenance, ResourceState.PrepareForMaintenance, ResourceState.Disabled); + sc.setJoinParameters("ClusterManagedSearch", "managed", Managed.ManagedState.Managed); + List hosts = lockRows(sc, new Filter(HostVO.class, "clusterId", true, 0L, limit), true); + + for (HostVO host : hosts) { + host.setManagementServerId(managementServerId); + update(host.getId(), host); + } + + txn.commit(); + + return hosts; + } + + @Override @DB + public List findAndUpdateApplianceToLoad(long lastPingSecondsAfter, long managementServerId) { + Transaction txn = Transaction.currentTxn(); + + txn.start(); + SearchCriteria sc = UnmanagedApplianceSearch.create(); + sc.setParameters("lastPinged", lastPingSecondsAfter); + sc.setParameters("types", Type.ExternalDhcp, Type.ExternalFirewall, Type.ExternalLoadBalancer, Type.PxeServer, Type.TrafficMonitor, Type.L2Networking); + List hosts = lockRows(sc, null, true); + + for (HostVO host : hosts) { + host.setManagementServerId(managementServerId); + update(host.getId(), host); + } + + txn.commit(); + + return hosts; + } + + @Override + public void markHostsAsDisconnected(long msId, long lastPing) { + SearchCriteria sc = MsStatusSearch.create(); + sc.setParameters("ms", msId); + + HostVO host = createForUpdate(); + host.setLastPinged(lastPing); + host.setDisconnectedOn(new Date()); + UpdateBuilder ub = getUpdateBuilder(host); + ub.set(host, "status", Status.Disconnected); + + update(ub, sc, null); + + sc = MsStatusSearch.create(); + sc.setParameters("ms", msId); + + host = createForUpdate(); + host.setManagementServerId(null); + host.setLastPinged((System.currentTimeMillis() >> 10) - (10 * 60)); + host.setDisconnectedOn(new Date()); + ub = getUpdateBuilder(host); + update(ub, sc, null); + } + + @Override + public List listByHostTag(Host.Type type, Long clusterId, Long podId, long dcId, String hostTag) { + + SearchBuilder hostTagSearch = _hostTagsDao.createSearchBuilder(); + HostTagVO tagEntity = hostTagSearch.entity(); + hostTagSearch.and("tag", tagEntity.getTag(), SearchCriteria.Op.EQ); + + SearchBuilder hostSearch = createSearchBuilder(); + HostVO entity = hostSearch.entity(); + hostSearch.and("type", entity.getType(), SearchCriteria.Op.EQ); + hostSearch.and("pod", entity.getPodId(), SearchCriteria.Op.EQ); + hostSearch.and("dc", entity.getDataCenterId(), SearchCriteria.Op.EQ); + hostSearch.and("cluster", entity.getClusterId(), SearchCriteria.Op.EQ); + hostSearch.and("status", entity.getStatus(), SearchCriteria.Op.EQ); + hostSearch.and("resourceState", entity.getResourceState(), SearchCriteria.Op.EQ); + hostSearch.join("hostTagSearch", hostTagSearch, entity.getId(), tagEntity.getHostId(), JoinBuilder.JoinType.INNER); + + SearchCriteria sc = hostSearch.create(); + sc.setJoinParameters("hostTagSearch", "tag", hostTag); + sc.setParameters("type", type.toString()); + if (podId != null) { + sc.setParameters("pod", podId); + } + if (clusterId != null) { + sc.setParameters("cluster", clusterId); + } + sc.setParameters("dc", dcId); + sc.setParameters("status", Status.Up.toString()); + sc.setParameters("resourceState", ResourceState.Enabled.toString()); + + return listBy(sc); + } + + + @Override + public List listAllUpAndEnabledNonHAHosts(Type type, Long clusterId, Long podId, long dcId, String haTag) { + SearchBuilder hostTagSearch = null; + if (haTag != null && !haTag.isEmpty()) { + hostTagSearch = _hostTagsDao.createSearchBuilder(); + hostTagSearch.and().op("tag", hostTagSearch.entity().getTag(), SearchCriteria.Op.NEQ); + hostTagSearch.or("tagNull", hostTagSearch.entity().getTag(), SearchCriteria.Op.NULL); + hostTagSearch.cp(); + } + + SearchBuilder hostSearch = createSearchBuilder(); + + hostSearch.and("type", hostSearch.entity().getType(), SearchCriteria.Op.EQ); + hostSearch.and("clusterId", hostSearch.entity().getClusterId(), SearchCriteria.Op.EQ); + hostSearch.and("podId", hostSearch.entity().getPodId(), SearchCriteria.Op.EQ); + hostSearch.and("zoneId", hostSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + hostSearch.and("status", hostSearch.entity().getStatus(), SearchCriteria.Op.EQ); + hostSearch.and("resourceState", hostSearch.entity().getResourceState(), SearchCriteria.Op.EQ); + + if (haTag != null && !haTag.isEmpty()) { + hostSearch.join("hostTagSearch", hostTagSearch, hostSearch.entity().getId(), hostTagSearch.entity().getHostId(), JoinBuilder.JoinType.LEFTOUTER); + } + + SearchCriteria sc = hostSearch.create(); + + if (haTag != null && !haTag.isEmpty()) { + sc.setJoinParameters("hostTagSearch", "tag", haTag); + } + + if (type != null) { + sc.setParameters("type", type); + } + + if (clusterId != null) { + sc.setParameters("clusterId", clusterId); + } + + if (podId != null) { + sc.setParameters("podId", podId); + } + + sc.setParameters("zoneId", dcId); + sc.setParameters("status", Status.Up); + sc.setParameters("resourceState", ResourceState.Enabled); + + return listBy(sc); + } + + @Override + public void loadDetails(HostVO host) { + Map details = _detailsDao.findDetails(host.getId()); + host.setDetails(details); + } + + @Override + public void loadHostTags(HostVO host) { + List hostTags = _hostTagsDao.gethostTags(host.getId()); + host.setHostTags(hostTags); + } + + @DB + @Override + public List findLostHosts(long timeout) { + Transaction txn = Transaction.currentTxn(); + PreparedStatement pstmt = null; + List result = new ArrayList(); + ResultSet rs = null; + try { + String sql = "select h.id from host h left join cluster c on h.cluster_id=c.id where h.mgmt_server_id is not null and h.last_ping < ? and h.status in ('Up', 'Updating', 'Disconnected', 'Connecting') and h.type not in ('ExternalFirewall', 'ExternalLoadBalancer', 'TrafficMonitor', 'SecondaryStorage', 'LocalSecondaryStorage', 'L2Networking') and (h.cluster_id is null or c.managed_state = 'Managed') ;" ; + pstmt = txn.prepareStatement(sql); + pstmt.setLong(1, timeout); + rs = pstmt.executeQuery(); + while (rs.next()) { + long id = rs.getLong(1); //ID column + result.add(findById(id)); + } + } catch (Exception e) { + s_logger.warn("Exception: ", e); + } finally { + try { + if (rs != null) { + rs.close(); + } + if (pstmt != null) { + pstmt.close(); + } + } catch (SQLException e) { + } + } + return result; + } + + @Override + public void saveDetails(HostVO host) { + Map details = host.getDetails(); + if (details == null) { + return; + } + _detailsDao.persist(host.getId(), details); + } + + protected void saveHostTags(HostVO host) { + List hostTags = host.getHostTags(); + if (hostTags == null || (hostTags != null && hostTags.isEmpty())) { + return; + } + _hostTagsDao.persist(host.getId(), hostTags); + } + + @Override + @DB + public HostVO persist(HostVO host) { + final String InsertSequenceSql = "INSERT INTO op_host(id) VALUES(?)"; + + Transaction txn = Transaction.currentTxn(); + txn.start(); + + HostVO dbHost = super.persist(host); + + try { + PreparedStatement pstmt = txn.prepareAutoCloseStatement(InsertSequenceSql); + pstmt.setLong(1, dbHost.getId()); + pstmt.executeUpdate(); + } catch (SQLException e) { + throw new CloudRuntimeException("Unable to persist the sequence number for this host"); + } + + saveDetails(host); + loadDetails(dbHost); + saveHostTags(host); + loadHostTags(dbHost); + + txn.commit(); + + return dbHost; + } + + @Override + @DB + public boolean update(Long hostId, HostVO host) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + + boolean persisted = super.update(hostId, host); + if (!persisted) { + return persisted; + } + + saveDetails(host); + saveHostTags(host); + + txn.commit(); + + return persisted; + } + + @Override + @DB + public List getRunningHostCounts(Date cutTime) { + String sql = "select * from (" + "select h.data_center_id, h.type, count(*) as count from host as h INNER JOIN mshost as m ON h.mgmt_server_id=m.msid " + + "where h.status='Up' and h.type='SecondaryStorage' and m.last_update > ? " + "group by h.data_center_id, h.type " + "UNION ALL " + + "select h.data_center_id, h.type, count(*) as count from host as h INNER JOIN mshost as m ON h.mgmt_server_id=m.msid " + + "where h.status='Up' and h.type='Routing' and m.last_update > ? " + "group by h.data_center_id, h.type) as t " + "ORDER by t.data_center_id, t.type"; + + ArrayList l = new ArrayList(); + + Transaction txn = Transaction.currentTxn(); + ; + PreparedStatement pstmt = null; + try { + pstmt = txn.prepareAutoCloseStatement(sql); + String gmtCutTime = DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutTime); + pstmt.setString(1, gmtCutTime); + pstmt.setString(2, gmtCutTime); + + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) { + RunningHostCountInfo info = new RunningHostCountInfo(); + info.setDcId(rs.getLong(1)); + info.setHostType(rs.getString(2)); + info.setCount(rs.getInt(3)); + + l.add(info); + } + } catch (SQLException e) { + } catch (Throwable e) { + } + return l; + } + + @Override + public long getNextSequence(long hostId) { + if (s_logger.isTraceEnabled()) { + s_logger.trace("getNextSequence(), hostId: " + hostId); + } + + TableGenerator tg = _tgs.get("host_req_sq"); + assert tg != null : "how can this be wrong!"; + + return s_seqFetcher.getNextSequence(Long.class, tg, hostId); + } + + /*TODO: this is used by mycloud, check if it needs resource state Enabled */ + @Override + public long countRoutingHostsByDataCenter(long dcId) { + SearchCriteria sc = CountRoutingByDc.create(); + sc.setParameters("dc", dcId); + sc.setParameters("type", Host.Type.Routing); + sc.setParameters("status", Status.Up.toString()); + return customSearch(sc, null).get(0); + } + + + @Override + public boolean updateState(State currentState, DataCenterResourceEntity.State.Event event, State nextState, DataCenterResourceEntity hostEntity, Object data) { + HostVO vo = findById(hostEntity.getId()); + Date oldUpdatedTime = vo.getLastUpdated(); + + SearchCriteria sc = StateChangeSearch.create(); + sc.setParameters("id", hostEntity.getId()); + sc.setParameters("state", currentState); + + UpdateBuilder builder = getUpdateBuilder(vo); + builder.set(vo, "state", nextState); + builder.set(vo, "lastUpdated", new Date()); + + int rows = update((HostVO) vo, sc); + + if (rows == 0 && s_logger.isDebugEnabled()) { + HostVO dbHost = findByIdIncludingRemoved(vo.getId()); + if (dbHost != null) { + StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString()); + str.append(": DB Data={id=").append(dbHost.getId()).append("; state=").append(dbHost.getState()).append(";updatedTime=") + .append(dbHost.getLastUpdated()); + str.append(": New Data={id=").append(vo.getId()).append("; state=").append(nextState).append("; event=").append(event).append("; updatedTime=").append(vo.getLastUpdated()); + str.append(": stale Data={id=").append(vo.getId()).append("; state=").append(currentState).append("; event=").append(event).append("; updatedTime=").append(oldUpdatedTime); + } else { + s_logger.debug("Unable to update dataCenter: id=" + vo.getId() + ", as there is no such dataCenter exists in the database anymore"); + } + } + return rows > 0; + } + + @Override + public boolean updateResourceState(ResourceState oldState, ResourceState.Event event, ResourceState newState, Host vo) { + HostVO host = (HostVO)vo; + SearchBuilder sb = createSearchBuilder(); + sb.and("resource_state", sb.entity().getResourceState(), SearchCriteria.Op.EQ); + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + sb.done(); + + SearchCriteria sc = sb.create(); + + sc.setParameters("resource_state", oldState); + sc.setParameters("id", host.getId()); + + UpdateBuilder ub = getUpdateBuilder(host); + ub.set(host, _resourceStateAttr, newState); + int result = update(ub, sc, null); + assert result <= 1 : "How can this update " + result + " rows? "; + + if (state_logger.isDebugEnabled() && result == 0) { + HostVO ho = findById(host.getId()); + assert ho != null : "How how how? : " + host.getId(); + + StringBuilder str = new StringBuilder("Unable to update resource state: ["); + str.append("m = " + host.getId()); + str.append("; name = " + host.getName()); + str.append("; old state = " + oldState); + str.append("; event = " + event); + str.append("; new state = " + newState + "]"); + state_logger.debug(str.toString()); + } else { + StringBuilder msg = new StringBuilder("Resource state update: ["); + msg.append("id = " + host.getId()); + msg.append("; name = " + host.getName()); + msg.append("; old state = " + oldState); + msg.append("; event = " + event); + msg.append("; new state = " + newState + "]"); + state_logger.debug(msg.toString()); + } + + return result > 0; + } + + @Override + public HostVO findByTypeNameAndZoneId(long zoneId, String name, Host.Type type) { + SearchCriteria sc = TypeNameZoneSearch.create(); + sc.setParameters("type", type); + sc.setParameters("name", name); + sc.setParameters("zoneId", zoneId); + return findOneBy(sc); + } + + @Override + public List findHypervisorHostInCluster(long clusterId) { + SearchCriteria sc = TypeClusterStatusSearch.create(); + sc.setParameters("type", Host.Type.Routing); + sc.setParameters("cluster", clusterId); + sc.setParameters("status", Status.Up); + sc.setParameters("resourceState", ResourceState.Enabled); + + return listBy(sc); + } + + @Override + public List lockRows( + SearchCriteria sc, + Filter filter, boolean exclusive) { + // TODO Auto-generated method stub + return null; + } + + @Override + public org.apache.cloudstack.engine.datacenter.entity.api.db.HostVO lockOneRandomRow( + SearchCriteria sc, + boolean exclusive) { + // TODO Auto-generated method stub + return null; + } + + + @Override + public List search( + SearchCriteria sc, + Filter filter) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List search( + SearchCriteria sc, + Filter filter, boolean enable_query_cache) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List searchIncludingRemoved( + SearchCriteria sc, + Filter filter, Boolean lock, boolean cache) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List searchIncludingRemoved( + SearchCriteria sc, + Filter filter, Boolean lock, boolean cache, + boolean enable_query_cache) { + // TODO Auto-generated method stub + return null; + } + + + @Override + public int remove( + SearchCriteria sc) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int expunge(SearchCriteria sc) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public HostVO findOneBy(SearchCriteria sc) { + // TODO Auto-generated method stub + return null; + } + + + + @Override + public HostVO findByUUID(String uuid) { + SearchCriteria sc = UUIDSearch.create(); + sc.setParameters("uuid", uuid); + return findOneBy(sc); + } + +} diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDetailsDao.java b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDetailsDao.java new file mode 100644 index 00000000000..d6455038f8e --- /dev/null +++ b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDetailsDao.java @@ -0,0 +1,32 @@ +// 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 org.apache.cloudstack.engine.datacenter.entity.api.db.dao; + +import java.util.Map; + +import com.cloud.host.DetailVO; +import com.cloud.utils.db.GenericDao; + +public interface HostDetailsDao extends GenericDao { + Map findDetails(long hostId); + + void persist(long hostId, Map details); + + DetailVO findDetail(long hostId, String name); + + void deleteDetails(long hostId); +} diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDetailsDaoImpl.java b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDetailsDaoImpl.java new file mode 100644 index 00000000000..93e728d3130 --- /dev/null +++ b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDetailsDaoImpl.java @@ -0,0 +1,110 @@ +// 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 org.apache.cloudstack.engine.datacenter.entity.api.db.dao; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ejb.Local; + +import org.springframework.stereotype.Component; + +import com.cloud.host.DetailVO; +import com.cloud.utils.crypt.DBEncryptionUtil; +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=HostDetailsDao.class) +public class HostDetailsDaoImpl extends GenericDaoBase implements HostDetailsDao { + protected final SearchBuilder HostSearch; + protected final SearchBuilder DetailSearch; + + protected HostDetailsDaoImpl() { + HostSearch = createSearchBuilder(); + HostSearch.and("hostId", HostSearch.entity().getHostId(), SearchCriteria.Op.EQ); + HostSearch.done(); + + DetailSearch = createSearchBuilder(); + DetailSearch.and("hostId", DetailSearch.entity().getHostId(), SearchCriteria.Op.EQ); + DetailSearch.and("name", DetailSearch.entity().getName(), SearchCriteria.Op.EQ); + DetailSearch.done(); + } + + @Override + public DetailVO findDetail(long hostId, String name) { + SearchCriteria sc = DetailSearch.create(); + sc.setParameters("hostId", hostId); + sc.setParameters("name", name); + + DetailVO detail = findOneIncludingRemovedBy(sc); + if("password".equals(name) && detail != null){ + detail.setValue(DBEncryptionUtil.decrypt(detail.getValue())); + } + return detail; + } + + @Override + public Map findDetails(long hostId) { + SearchCriteria sc = HostSearch.create(); + sc.setParameters("hostId", hostId); + + List results = search(sc, null); + Map details = new HashMap(results.size()); + for (DetailVO result : results) { + if("password".equals(result.getName())){ + details.put(result.getName(), DBEncryptionUtil.decrypt(result.getValue())); + } else { + details.put(result.getName(), result.getValue()); + } + } + return details; + } + + @Override + public void deleteDetails(long hostId) { + SearchCriteria sc = HostSearch.create(); + sc.setParameters("hostId", hostId); + + List results = search(sc, null); + for (DetailVO result : results) { + remove(result.getId()); + } + } + + @Override + public void persist(long hostId, Map details) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + SearchCriteria sc = HostSearch.create(); + sc.setParameters("hostId", hostId); + expunge(sc); + + for (Map.Entry detail : details.entrySet()) { + String value = detail.getValue(); + if("password".equals(detail.getKey())){ + value = DBEncryptionUtil.encrypt(value); + } + DetailVO vo = new DetailVO(hostId, detail.getKey(), value); + persist(vo); + } + txn.commit(); + } +} diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostTagsDao.java b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostTagsDao.java new file mode 100644 index 00000000000..09503d80127 --- /dev/null +++ b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostTagsDao.java @@ -0,0 +1,30 @@ +// 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 org.apache.cloudstack.engine.datacenter.entity.api.db.dao; + +import java.util.List; +import com.cloud.host.HostTagVO; +import com.cloud.utils.db.GenericDao; + +public interface HostTagsDao extends GenericDao { + + void persist(long hostId, List hostTags); + + List gethostTags(long hostId); + +} + diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostTagsDaoImpl.java b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostTagsDaoImpl.java new file mode 100644 index 00000000000..2ad36319cb7 --- /dev/null +++ b/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostTagsDaoImpl.java @@ -0,0 +1,75 @@ +// 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 org.apache.cloudstack.engine.datacenter.entity.api.db.dao; + +import java.util.ArrayList; +import java.util.List; + +import javax.ejb.Local; + +import org.springframework.stereotype.Component; + +import com.cloud.host.HostTagVO; +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=HostTagsDao.class) +public class HostTagsDaoImpl extends GenericDaoBase implements HostTagsDao { + protected final SearchBuilder HostSearch; + + protected HostTagsDaoImpl() { + HostSearch = createSearchBuilder(); + HostSearch.and("hostId", HostSearch.entity().getHostId(), SearchCriteria.Op.EQ); + HostSearch.done(); + } + + @Override + public List gethostTags(long hostId) { + SearchCriteria sc = HostSearch.create(); + sc.setParameters("hostId", hostId); + + List results = search(sc, null); + List hostTags = new ArrayList(results.size()); + for (HostTagVO result : results) { + hostTags.add(result.getTag()); + } + + return hostTags; + } + + @Override + public void persist(long hostId, List hostTags) { + Transaction txn = Transaction.currentTxn(); + + txn.start(); + SearchCriteria sc = HostSearch.create(); + sc.setParameters("hostId", hostId); + expunge(sc); + + for (String tag : hostTags) { + tag = tag.trim(); + if(tag.length() > 0) { + HostTagVO vo = new HostTagVO(hostId, tag); + persist(vo); + } + } + txn.commit(); + } +} diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/service/api/ProvisioningServiceImpl.java b/engine/orchestration/src/org/apache/cloudstack/engine/service/api/ProvisioningServiceImpl.java index 2dc652f20d5..f503530e194 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/service/api/ProvisioningServiceImpl.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/service/api/ProvisioningServiceImpl.java @@ -32,6 +32,8 @@ import org.apache.cloudstack.engine.datacenter.entity.api.ClusterEntity; import org.apache.cloudstack.engine.datacenter.entity.api.ClusterEntityImpl; import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity.State; import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceManager; +import org.apache.cloudstack.engine.datacenter.entity.api.HostEntity; +import org.apache.cloudstack.engine.datacenter.entity.api.HostEntityImpl; import org.apache.cloudstack.engine.datacenter.entity.api.PodEntity; import org.apache.cloudstack.engine.datacenter.entity.api.PodEntityImpl; import org.apache.cloudstack.engine.datacenter.entity.api.StorageEntity; @@ -89,9 +91,14 @@ public class ProvisioningServiceImpl implements ProvisioningService { } @Override - public String registerHost(String name, List tags, Map details) { - // TODO Auto-generated method stub - return null; + public HostEntity registerHost(String hostUuid, String name, String owner, List tags, Map details) { + HostEntityImpl hostEntity = new HostEntityImpl(hostUuid, manager); + hostEntity.setOwner(owner); + hostEntity.setName(name); + hostEntity.setDetails(details); + + hostEntity.persist(); + return hostEntity; } @Override @@ -120,9 +127,9 @@ public class ProvisioningServiceImpl implements ProvisioningService { } @Override - public void deregisterHost() { - // TODO Auto-generated method stub - + public void deregisterHost(String uuid) { + HostEntityImpl hostEntity = new HostEntityImpl(uuid, manager); + hostEntity.disable(); } @Override diff --git a/engine/orchestration/test/org/apache/cloudstack/engine/provisioning/test/ChildTestConfiguration.java b/engine/orchestration/test/org/apache/cloudstack/engine/provisioning/test/ChildTestConfiguration.java index 13e44abd68f..72f956ecf15 100644 --- a/engine/orchestration/test/org/apache/cloudstack/engine/provisioning/test/ChildTestConfiguration.java +++ b/engine/orchestration/test/org/apache/cloudstack/engine/provisioning/test/ChildTestConfiguration.java @@ -3,6 +3,7 @@ package org.apache.cloudstack.engine.provisioning.test; import org.apache.cloudstack.engine.datacenter.entity.api.db.dao.ClusterDao; import org.apache.cloudstack.engine.datacenter.entity.api.db.dao.DataCenterDao; +import org.apache.cloudstack.engine.datacenter.entity.api.db.dao.HostDao; import org.apache.cloudstack.engine.datacenter.entity.api.db.dao.HostPodDao; import org.mockito.Mockito; import org.springframework.context.annotation.Bean; @@ -27,4 +28,8 @@ public class ChildTestConfiguration { return Mockito.mock(ClusterDao.class); } + @Bean + public HostDao hostDao() { + return Mockito.mock(HostDao.class); + } } diff --git a/engine/orchestration/test/org/apache/cloudstack/engine/provisioning/test/ProvisioningTest.java b/engine/orchestration/test/org/apache/cloudstack/engine/provisioning/test/ProvisioningTest.java index 72ad83402af..70b5b93c4fb 100644 --- a/engine/orchestration/test/org/apache/cloudstack/engine/provisioning/test/ProvisioningTest.java +++ b/engine/orchestration/test/org/apache/cloudstack/engine/provisioning/test/ProvisioningTest.java @@ -12,10 +12,12 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.datacenter.entity.api.ClusterEntity; import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity.State; +import org.apache.cloudstack.engine.datacenter.entity.api.HostEntity; import org.apache.cloudstack.engine.datacenter.entity.api.PodEntity; import org.apache.cloudstack.engine.datacenter.entity.api.ZoneEntity; import org.apache.cloudstack.engine.datacenter.entity.api.db.dao.ClusterDao; import org.apache.cloudstack.engine.datacenter.entity.api.db.dao.DataCenterDao; +import org.apache.cloudstack.engine.datacenter.entity.api.db.dao.HostDao; import org.apache.cloudstack.engine.datacenter.entity.api.db.dao.HostPodDao; import org.apache.cloudstack.engine.service.api.ProvisioningService; import org.junit.Before; @@ -28,6 +30,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.apache.cloudstack.engine.datacenter.entity.api.db.ClusterVO; import org.apache.cloudstack.engine.datacenter.entity.api.db.DataCenterVO; import org.apache.cloudstack.engine.datacenter.entity.api.db.HostPodVO; +import org.apache.cloudstack.engine.datacenter.entity.api.db.HostVO; import com.cloud.dc.DataCenter.NetworkType; @@ -49,6 +52,8 @@ public class ProvisioningTest extends TestCase { @Inject ClusterDao _clusterDao; + @Inject + HostDao _hostDao; @Before public void setUp() { @@ -63,7 +68,12 @@ public class ProvisioningTest extends TestCase { ClusterVO cluster = new ClusterVO(); Mockito.when(_clusterDao.findByUUID(Mockito.anyString())).thenReturn(cluster); - Mockito.when(_clusterDao.persist((ClusterVO) Mockito.anyObject())).thenReturn(cluster); + Mockito.when(_clusterDao.persist((ClusterVO) Mockito.anyObject())).thenReturn(cluster); + + HostVO host = new HostVO("68765876598"); + Mockito.when(_hostDao.findByUUID(Mockito.anyString())).thenReturn(host); + Mockito.when(_hostDao.persist((HostVO) Mockito.anyObject())).thenReturn(host); + } private void registerAndEnableZone() { @@ -90,12 +100,21 @@ public class ProvisioningTest extends TestCase { boolean result = cluster.enable(); System.out.println("result:"+result); } + + private void registerAndEnableHost() { + HostEntity host = service.registerHost("1265476542", "lab","owner", null, new HashMap()); + State state = host.getState(); + System.out.println("state:"+state); + boolean result = host.enable(); + System.out.println("result:"+result); + } @Test public void testProvisioning() { - registerAndEnableZone(); - registerAndEnablePod(); - registerAndEnableCluster(); + //registerAndEnableZone(); + //registerAndEnablePod(); + //registerAndEnableCluster(); + registerAndEnableHost(); }