Skip to content

Commit adbebc1

Browse files
committed
Changes for implicitly dedicating a resource. It includes a following:
1. A new implicit planner which extends the functionality provided by FirstFitPlanner. 2. Implicit planner can be used in either strict or preferred mode. In strict mode it tries to deploy a vm of a given account on a host on which vms of the account are already running. If no such host is found it'll search for an empty host to service the request. Otherwise the deploy vm request fails. 3. In preferred mode, if a host which is running vms of the account or an empty host isn't found, the planner then tries to deploy on any other host provided it isn't running implicitly dedicated strict vms of any other account. 4. Updated the createServiceOffering api to configure the details for the planner that the service offering is using. 5. Made db changes to store the service offering details for the planner. 6. Unit tests for testing the implicit planner functionality. 7. Marvin test for validating the functionality.
1 parent caf0dd2 commit adbebc1

23 files changed

Lines changed: 1430 additions & 18 deletions

File tree

api/src/com/cloud/deploy/DeploymentPlanner.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,13 @@ public void addHost(long hostId) {
213213
_hostIds.add(hostId);
214214
}
215215

216+
public void addHostList(Collection<Long> hostList) {
217+
if (_hostIds == null) {
218+
_hostIds = new HashSet<Long>();
219+
}
220+
_hostIds.addAll(hostList);
221+
}
222+
216223
public boolean shouldAvoid(Host host) {
217224
if (_dcIds != null && _dcIds.contains(host.getDataCenterId())) {
218225
return true;

api/src/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ public class ApiConstants {
312312
public static final String ACCEPT = "accept";
313313
public static final String SORT_KEY = "sortkey";
314314
public static final String ACCOUNT_DETAILS = "accountdetails";
315+
public static final String SERVICE_OFFERING_DETAILS = "serviceofferingdetails";
315316
public static final String SERVICE_PROVIDER_LIST = "serviceproviderlist";
316317
public static final String SERVICE_CAPABILITY_LIST = "servicecapabilitylist";
317318
public static final String CAN_CHOOSE_SERVICE_CAPABILITY = "canchooseservicecapability";

api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
// under the License.
1717
package org.apache.cloudstack.api.command.admin.offering;
1818

19+
import java.util.Collection;
20+
import java.util.Map;
21+
1922
import org.apache.cloudstack.api.APICommand;
2023
import org.apache.cloudstack.api.ApiConstants;
2124
import org.apache.cloudstack.api.ApiErrorCode;
@@ -87,6 +90,9 @@ public class CreateServiceOfferingCmd extends BaseCmd {
8790
@Parameter(name = ApiConstants.DEPLOYMENT_PLANNER, type = CommandType.STRING, description = "The deployment planner heuristics used to deploy a VM of this offering. If null, value of global config vm.deployment.planner is used")
8891
private String deploymentPlanner;
8992

93+
@Parameter(name = ApiConstants.SERVICE_OFFERING_DETAILS, type = CommandType.MAP, description = "details for planner, used to store specific parameters")
94+
private Map<String, String> details;
95+
9096
/////////////////////////////////////////////////////
9197
/////////////////// Accessors ///////////////////////
9298
/////////////////////////////////////////////////////
@@ -155,6 +161,16 @@ public String getDeploymentPlanner() {
155161
return deploymentPlanner;
156162
}
157163

164+
public Map<String, String> getDetails() {
165+
if (details == null || details.isEmpty()) {
166+
return null;
167+
}
168+
169+
Collection<String> paramsCollection = details.values();
170+
Map<String, String> params = (Map<String, String>)(paramsCollection.toArray())[0];
171+
return params;
172+
}
173+
158174
/////////////////////////////////////////////////////
159175
/////////////// API Implementation///////////////////
160176
/////////////////////////////////////////////////////

client/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@
131131
<artifactId>cloud-plugin-planner-user-concentrated-pod</artifactId>
132132
<version>${project.version}</version>
133133
</dependency>
134+
<dependency>
135+
<groupId>org.apache.cloudstack</groupId>
136+
<artifactId>cloud-plugin-planner-implicit-dedication</artifactId>
137+
<version>${project.version}</version>
138+
</dependency>
134139
<dependency>
135140
<groupId>org.apache.cloudstack</groupId>
136141
<artifactId>cloud-plugin-host-allocator-random</artifactId>

client/tomcatconf/applicationContext.xml.in

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@
370370
<bean id="vpnUserDaoImpl" class="com.cloud.network.dao.VpnUserDaoImpl" />
371371
<bean id="applicationLbRuleDaoImpl" class="org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDaoImpl" />
372372
<bean id="networkOfferingDetailsDaoImpl" class="com.cloud.offerings.dao.NetworkOfferingDetailsDaoImpl" />
373-
373+
<bean id="serviceOfferingDetailsDaoImpl" class="com.cloud.service.dao.ServiceOfferingDetailsDaoImpl"/>
374374

375375
<!--
376376
Checkers
@@ -547,6 +547,10 @@
547547
<property name="name" value="UserConcentratedPodPlanner"/>
548548
</bean>
549549

550+
<bean id="ImplicitDedicationPlanner" class="com.cloud.deploy.ImplicitDedicationPlanner">
551+
<property name="name" value="ImplicitDedicationPlanner"/>
552+
</bean>
553+
550554
<bean id="clusterBasedAgentLoadBalancerPlanner" class="com.cloud.cluster.agentlb.ClusterBasedAgentLoadBalancerPlanner">
551555
<property name="name" value="ClusterBasedAgentLoadBalancerPlanner"/>
552556
</bean>

client/tomcatconf/componentContext.xml.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@
156156
<ref bean="FirstFitPlanner" />
157157
<ref bean="UserDispersingPlanner" />
158158
<ref bean="UserConcentratedPodPlanner" />
159+
<ref bean="ImplicitDedicationPlanner" />
159160
<!--
160161
<ref bean="BareMetalPlanner" />
161162
-->
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package com.cloud.service;
18+
19+
import org.apache.cloudstack.api.InternalIdentity;
20+
21+
import javax.persistence.Column;
22+
import javax.persistence.Entity;
23+
import javax.persistence.GeneratedValue;
24+
import javax.persistence.GenerationType;
25+
import javax.persistence.Id;
26+
import javax.persistence.Table;
27+
28+
@Entity
29+
@Table(name="service_offering_details")
30+
public class ServiceOfferingDetailsVO implements InternalIdentity {
31+
@Id
32+
@GeneratedValue(strategy=GenerationType.IDENTITY)
33+
@Column(name="id")
34+
private long id;
35+
36+
@Column(name="service_offering_id")
37+
private long serviceOfferingId;
38+
39+
@Column(name="name")
40+
private String name;
41+
42+
@Column(name="value")
43+
private String value;
44+
45+
protected ServiceOfferingDetailsVO() {
46+
}
47+
48+
public ServiceOfferingDetailsVO(long serviceOfferingId, String name, String value) {
49+
this.serviceOfferingId = serviceOfferingId;
50+
this.name = name;
51+
this.value = value;
52+
}
53+
54+
public long getServiceOfferingId() {
55+
return serviceOfferingId;
56+
}
57+
58+
public String getName() {
59+
return name;
60+
}
61+
62+
public String getValue() {
63+
return value;
64+
}
65+
66+
public void setValue(String value) {
67+
this.value = value;
68+
}
69+
70+
public long getId() {
71+
return id;
72+
}
73+
}

engine/schema/src/com/cloud/service/ServiceOfferingVO.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
// under the License.
1717
package com.cloud.service;
1818

19+
import java.util.Map;
20+
1921
import javax.persistence.Column;
2022
import javax.persistence.DiscriminatorValue;
2123
import javax.persistence.Entity;
@@ -71,6 +73,12 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
7173
@Column(name = "deployment_planner")
7274
private String deploymentPlanner = null;
7375

76+
// This is a delayed load value. If the value is null,
77+
// then this field has not been loaded yet.
78+
// Call service offering dao to load it.
79+
@Transient
80+
Map<String, String> details;
81+
7482
protected ServiceOfferingVO() {
7583
super();
7684
}
@@ -225,4 +233,23 @@ public String getDeploymentPlanner() {
225233
return deploymentPlanner;
226234
}
227235

236+
public Map<String, String> getDetails() {
237+
return details;
238+
}
239+
240+
public String getDetail(String name) {
241+
assert (details != null) : "Did you forget to load the details?";
242+
243+
return details != null ? details.get(name) : null;
244+
}
245+
246+
public void setDetail(String name, String value) {
247+
assert (details != null) : "Did you forget to load the details?";
248+
249+
details.put(name, value);
250+
}
251+
252+
public void setDetails(Map<String, String> details) {
253+
this.details = details;
254+
}
228255
}

engine/schema/src/com/cloud/service/dao/ServiceOfferingDao.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,6 @@ public interface ServiceOfferingDao extends GenericDao<ServiceOfferingVO, Long>
3131
List<ServiceOfferingVO> findServiceOfferingByDomainId(Long domainId);
3232
List<ServiceOfferingVO> findSystemOffering(Long domainId, Boolean isSystem, String vm_type);
3333
ServiceOfferingVO persistDeafultServiceOffering(ServiceOfferingVO offering);
34+
void loadDetails(ServiceOfferingVO serviceOffering);
35+
void saveDetails(ServiceOfferingVO serviceOffering);
3436
}

engine/schema/src/com/cloud/service/dao/ServiceOfferingDaoImpl.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,16 @@
1818

1919
import java.util.Date;
2020
import java.util.List;
21+
import java.util.Map;
2122

2223
import javax.ejb.Local;
24+
import javax.inject.Inject;
2325
import javax.persistence.EntityExistsException;
2426

2527
import org.apache.log4j.Logger;
2628
import org.springframework.stereotype.Component;
2729

2830
import com.cloud.service.ServiceOfferingVO;
29-
import com.cloud.storage.DiskOfferingVO;
3031
import com.cloud.utils.db.DB;
3132
import com.cloud.utils.db.GenericDaoBase;
3233
import com.cloud.utils.db.SearchBuilder;
@@ -37,6 +38,8 @@
3738
public class ServiceOfferingDaoImpl extends GenericDaoBase<ServiceOfferingVO, Long> implements ServiceOfferingDao {
3839
protected static final Logger s_logger = Logger.getLogger(ServiceOfferingDaoImpl.class);
3940

41+
@Inject protected ServiceOfferingDetailsDao detailsDao;
42+
4043
protected final SearchBuilder<ServiceOfferingVO> UniqueNameSearch;
4144
protected final SearchBuilder<ServiceOfferingVO> ServiceOfferingsByDomainIdSearch;
4245
protected final SearchBuilder<ServiceOfferingVO> SystemServiceOffering;
@@ -154,4 +157,18 @@ public boolean remove(Long id) {
154157

155158
return update(id, offering);
156159
}
160+
161+
@Override
162+
public void loadDetails(ServiceOfferingVO serviceOffering) {
163+
Map<String, String> details = detailsDao.findDetails(serviceOffering.getId());
164+
serviceOffering.setDetails(details);
165+
}
166+
167+
@Override
168+
public void saveDetails(ServiceOfferingVO serviceOffering) {
169+
Map<String, String> details = serviceOffering.getDetails();
170+
if (details != null) {
171+
detailsDao.persist(serviceOffering.getId(), details);
172+
}
173+
}
157174
}

0 commit comments

Comments
 (0)