Skip to content

Commit 93f3182

Browse files
authored
Hypervisor as class (#8798)
* HypervisorType as a class * Fixup * fixup * Add missing annotation * Resolve comments * Handle parallels typo * Add missing @convert annotation
1 parent a0b642c commit 93f3182

File tree

33 files changed

+369
-250
lines changed

33 files changed

+369
-250
lines changed

api/src/main/java/com/cloud/hypervisor/Hypervisor.java

Lines changed: 77 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -17,55 +17,45 @@
1717
package com.cloud.hypervisor;
1818

1919
import com.cloud.storage.Storage.ImageFormat;
20+
import org.apache.commons.lang3.StringUtils;
2021

21-
import java.util.HashMap;
22+
import java.util.LinkedHashMap;
2223
import java.util.Locale;
2324
import java.util.Map;
25+
import java.util.Objects;
2426

2527
public class Hypervisor {
28+
public static class HypervisorType {
29+
private static final Map<String, HypervisorType> hypervisorTypeMap = new LinkedHashMap<>();
30+
public static final HypervisorType None = new HypervisorType("None"); //for storage hosts
31+
public static final HypervisorType XenServer = new HypervisorType("XenServer", ImageFormat.VHD);
32+
public static final HypervisorType KVM = new HypervisorType("KVM", ImageFormat.QCOW2);
33+
public static final HypervisorType VMware = new HypervisorType("VMware", ImageFormat.OVA);
34+
public static final HypervisorType Hyperv = new HypervisorType("Hyperv");
35+
public static final HypervisorType VirtualBox = new HypervisorType("VirtualBox");
36+
public static final HypervisorType Parralels = new HypervisorType("Parralels");
37+
public static final HypervisorType BareMetal = new HypervisorType("BareMetal");
38+
public static final HypervisorType Simulator = new HypervisorType("Simulator");
39+
public static final HypervisorType Ovm = new HypervisorType("Ovm", ImageFormat.RAW);
40+
public static final HypervisorType Ovm3 = new HypervisorType("Ovm3", ImageFormat.RAW);
41+
public static final HypervisorType LXC = new HypervisorType("LXC");
42+
public static final HypervisorType Custom = new HypervisorType("Custom");
43+
public static final HypervisorType Any = new HypervisorType("Any"); /*If you don't care about the hypervisor type*/
44+
private final String name;
45+
private final ImageFormat imageFormat;
2646

27-
static Map<String, HypervisorType> hypervisorTypeMap;
28-
static Map<HypervisorType, ImageFormat> supportedImageFormatMap;
29-
30-
public enum HypervisorType {
31-
None, //for storage hosts
32-
XenServer,
33-
KVM,
34-
VMware,
35-
Hyperv,
36-
VirtualBox,
37-
Parralels,
38-
BareMetal,
39-
Simulator,
40-
Ovm,
41-
Ovm3,
42-
LXC,
43-
Custom,
44-
45-
Any; /*If you don't care about the hypervisor type*/
46-
47-
static {
48-
hypervisorTypeMap = new HashMap<>();
49-
hypervisorTypeMap.put("xenserver", HypervisorType.XenServer);
50-
hypervisorTypeMap.put("kvm", HypervisorType.KVM);
51-
hypervisorTypeMap.put("vmware", HypervisorType.VMware);
52-
hypervisorTypeMap.put("hyperv", HypervisorType.Hyperv);
53-
hypervisorTypeMap.put("virtualbox", HypervisorType.VirtualBox);
54-
hypervisorTypeMap.put("parallels", HypervisorType.Parralels);
55-
hypervisorTypeMap.put("baremetal", HypervisorType.BareMetal);
56-
hypervisorTypeMap.put("simulator", HypervisorType.Simulator);
57-
hypervisorTypeMap.put("ovm", HypervisorType.Ovm);
58-
hypervisorTypeMap.put("lxc", HypervisorType.LXC);
59-
hypervisorTypeMap.put("any", HypervisorType.Any);
60-
hypervisorTypeMap.put("ovm3", HypervisorType.Ovm3);
61-
hypervisorTypeMap.put("custom", HypervisorType.Custom);
62-
63-
supportedImageFormatMap = new HashMap<>();
64-
supportedImageFormatMap.put(HypervisorType.XenServer, ImageFormat.VHD);
65-
supportedImageFormatMap.put(HypervisorType.KVM, ImageFormat.QCOW2);
66-
supportedImageFormatMap.put(HypervisorType.VMware, ImageFormat.OVA);
67-
supportedImageFormatMap.put(HypervisorType.Ovm, ImageFormat.RAW);
68-
supportedImageFormatMap.put(HypervisorType.Ovm3, ImageFormat.RAW);
47+
public HypervisorType(String name) {
48+
this(name, null);
49+
}
50+
51+
public HypervisorType(String name, ImageFormat imageFormat) {
52+
this.name = name;
53+
this.imageFormat = imageFormat;
54+
if (name.equals("Parralels")){ // typo in the original code
55+
hypervisorTypeMap.put("parallels", this);
56+
} else {
57+
hypervisorTypeMap.putIfAbsent(name.toLowerCase(Locale.ROOT), this);
58+
}
6959
}
7060

7161
public static HypervisorType getType(String hypervisor) {
@@ -75,24 +65,62 @@ public static HypervisorType getType(String hypervisor) {
7565
hypervisorTypeMap.getOrDefault(hypervisor.toLowerCase(Locale.ROOT), HypervisorType.None));
7666
}
7767

68+
public static HypervisorType[] values() {
69+
return hypervisorTypeMap.values().toArray(HypervisorType[]::new).clone();
70+
}
71+
72+
public static HypervisorType valueOf(String name) {
73+
if (StringUtils.isBlank(name)) {
74+
return null;
75+
}
76+
77+
HypervisorType hypervisorType = hypervisorTypeMap.get(name.toLowerCase(Locale.ROOT));
78+
if (hypervisorType == null) {
79+
throw new IllegalArgumentException("HypervisorType '" + name + "' not found");
80+
}
81+
return hypervisorType;
82+
}
83+
7884
/**
7985
* Returns the display name of a hypervisor type in case the custom hypervisor is used,
8086
* using the 'hypervisor.custom.display.name' setting. Otherwise, returns hypervisor name
8187
*/
8288
public String getHypervisorDisplayName() {
83-
return !Hypervisor.HypervisorType.Custom.equals(this) ?
84-
this.toString() :
85-
HypervisorGuru.HypervisorCustomDisplayName.value();
89+
return HypervisorType.Custom.equals(this) ? HypervisorGuru.HypervisorCustomDisplayName.value() : name;
8690
}
8791

8892
/**
8993
* This method really needs to be part of the properties of the hypervisor type itself.
9094
*
91-
* @param hyperType
9295
* @return
9396
*/
94-
public static ImageFormat getSupportedImageFormat(HypervisorType hyperType) {
95-
return supportedImageFormatMap.getOrDefault(hyperType, null);
97+
public ImageFormat getSupportedImageFormat() {
98+
return imageFormat;
99+
}
100+
101+
public String name() {
102+
return name;
103+
}
104+
105+
@Override
106+
public int hashCode() {
107+
return Objects.hash(name);
108+
}
109+
110+
@Override
111+
public boolean equals(Object o) {
112+
if (o == this) {
113+
return true;
114+
} else if (o == null || getClass() != o.getClass()) {
115+
return false;
116+
}
117+
HypervisorType that = (HypervisorType) o;
118+
return Objects.equals(name, that.name);
119+
}
120+
121+
@Override
122+
public String toString() {
123+
return name;
96124
}
97125
}
98126

core/src/main/java/com/cloud/serializer/GsonHelper.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
import java.util.List;
2323

24+
import com.cloud.hypervisor.Hypervisor;
25+
import org.apache.cloudstack.transport.HypervisorTypeAdaptor;
2426
import org.apache.logging.log4j.Logger;
2527
import org.apache.logging.log4j.LogManager;
2628

@@ -75,6 +77,7 @@ static Gson setDefaultGsonConfig(GsonBuilder builder) {
7577
builder.registerTypeAdapter(new TypeToken<Pair<Long, Long>>() {
7678
}.getType(), new NwGroupsCommandTypeAdaptor());
7779
builder.registerTypeAdapter(Storage.StoragePoolType.class, new StoragePoolTypeAdaptor());
80+
builder.registerTypeAdapter(Hypervisor.HypervisorType.class, new HypervisorTypeAdaptor());
7881
Gson gson = builder.create();
7982
dsAdaptor.initGson(gson);
8083
dtAdaptor.initGson(gson);
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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 org.apache.cloudstack.transport;
18+
19+
import com.cloud.hypervisor.Hypervisor.HypervisorType;
20+
import com.google.gson.JsonDeserializationContext;
21+
import com.google.gson.JsonDeserializer;
22+
import com.google.gson.JsonElement;
23+
import com.google.gson.JsonNull;
24+
import com.google.gson.JsonParseException;
25+
import com.google.gson.JsonPrimitive;
26+
import com.google.gson.JsonSerializationContext;
27+
import com.google.gson.JsonSerializer;
28+
29+
import java.lang.reflect.Type;
30+
31+
/**
32+
* {@link HypervisorType} acts as extendable set of singleton objects and should return same result when used "=="
33+
* or {@link Object#equals(Object)}.
34+
* To support that, need to return existing object for a given name instead of creating new.
35+
*/
36+
public class HypervisorTypeAdaptor implements JsonDeserializer<HypervisorType>, JsonSerializer<HypervisorType> {
37+
@Override
38+
public HypervisorType deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
39+
if (json instanceof JsonPrimitive && ((JsonPrimitive) json).isString()) {
40+
return HypervisorType.valueOf(json.getAsString());
41+
}
42+
return null;
43+
}
44+
45+
@Override
46+
public JsonElement serialize(HypervisorType src, Type typeOfSrc, JsonSerializationContext context) {
47+
String name = src.name();
48+
if (name == null) {
49+
return new JsonNull();
50+
}
51+
return new JsonPrimitive(name);
52+
}
53+
}

engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1735,17 +1735,12 @@ public boolean getExecuteInSequence(final HypervisorType hypervisorType) {
17351735
return ExecuteInSequence.value();
17361736
}
17371737

1738-
switch (hypervisorType) {
1739-
case KVM:
1740-
case XenServer:
1741-
case Hyperv:
1742-
case LXC:
1743-
return false;
1744-
case VMware:
1745-
return StorageManager.shouldExecuteInSequenceOnVmware();
1746-
default:
1747-
return ExecuteInSequence.value();
1738+
if (Set.of(HypervisorType.KVM, HypervisorType.XenServer, HypervisorType.Hyperv, HypervisorType.LXC).contains(hypervisorType)) {
1739+
return false;
1740+
} else if (hypervisorType.equals(HypervisorType.VMware)) {
1741+
return StorageManager.shouldExecuteInSequenceOnVmware();
17481742
}
1743+
return ExecuteInSequence.value();
17491744
}
17501745

17511746
@Override

engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineClusterVO.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@
2626
import org.apache.cloudstack.api.Identity;
2727
import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity.State;
2828
import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity.State.Event;
29+
import org.apache.cloudstack.util.HypervisorTypeConverter;
2930

3031
import javax.persistence.Column;
32+
import javax.persistence.Convert;
3133
import javax.persistence.Entity;
3234
import javax.persistence.EnumType;
3335
import javax.persistence.Enumerated;
@@ -62,6 +64,7 @@ public class EngineClusterVO implements EngineCluster, Identity {
6264
long podId;
6365

6466
@Column(name = "hypervisor_type")
67+
@Convert(converter = HypervisorTypeConverter.class)
6568
String hypervisorType;
6669

6770
@Column(name = "cluster_type")

engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineHostVO.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import com.cloud.utils.NumbersUtil;
5151
import com.cloud.utils.db.GenericDao;
5252
import com.cloud.utils.db.StateMachine;
53+
import org.apache.cloudstack.util.HypervisorTypeConverter;
5354

5455
@Entity
5556
@Table(name = "host")
@@ -118,7 +119,7 @@ public class EngineHostVO implements EngineHost, Identity {
118119
private String storageMacAddressDeux;
119120

120121
@Column(name = "hypervisor_type", updatable = true, nullable = false)
121-
@Enumerated(value = EnumType.STRING)
122+
@Convert(converter = HypervisorTypeConverter.class)
122123
private HypervisorType hypervisorType;
123124

124125
@Column(name = "proxy_port")

engine/schema/src/main/java/com/cloud/dc/ClusterVO.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
import com.cloud.org.Managed.ManagedState;
2323
import com.cloud.utils.NumbersUtil;
2424
import com.cloud.utils.db.GenericDao;
25+
import org.apache.cloudstack.util.HypervisorTypeConverter;
2526

2627
import javax.persistence.Column;
28+
import javax.persistence.Convert;
2729
import javax.persistence.Entity;
2830
import javax.persistence.EnumType;
2931
import javax.persistence.Enumerated;
@@ -56,6 +58,7 @@ public class ClusterVO implements Cluster {
5658
long podId;
5759

5860
@Column(name = "hypervisor_type")
61+
@Convert(converter = HypervisorTypeConverter.class)
5962
String hypervisorType;
6063

6164
@Column(name = "cluster_type")

engine/schema/src/main/java/com/cloud/host/HostVO.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import javax.persistence.TemporalType;
4343
import javax.persistence.Transient;
4444

45+
import org.apache.cloudstack.util.HypervisorTypeConverter;
4546
import org.apache.cloudstack.utils.jsinterpreter.TagAsRuleHelper;
4647
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
4748
import org.apache.commons.lang.BooleanUtils;
@@ -125,7 +126,7 @@ public class HostVO implements Host {
125126
private String storageMacAddressDeux;
126127

127128
@Column(name = "hypervisor_type", updatable = true, nullable = false)
128-
@Enumerated(value = EnumType.STRING)
129+
@Convert(converter = HypervisorTypeConverter.class)
129130
private HypervisorType hypervisorType;
130131

131132
@Column(name = "proxy_port")

engine/schema/src/main/java/com/cloud/hypervisor/HypervisorCapabilitiesVO.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,16 @@
1919
import java.util.UUID;
2020

2121
import javax.persistence.Column;
22+
import javax.persistence.Convert;
2223
import javax.persistence.Entity;
23-
import javax.persistence.EnumType;
24-
import javax.persistence.Enumerated;
2524
import javax.persistence.GeneratedValue;
2625
import javax.persistence.GenerationType;
2726
import javax.persistence.Id;
2827
import javax.persistence.Table;
2928

3029
import com.cloud.hypervisor.Hypervisor.HypervisorType;
3130
import com.cloud.utils.NumbersUtil;
31+
import org.apache.cloudstack.util.HypervisorTypeConverter;
3232

3333
@Entity
3434
@Table(name = "hypervisor_capabilities")
@@ -39,7 +39,7 @@ public class HypervisorCapabilitiesVO implements HypervisorCapabilities {
3939
private long id;
4040

4141
@Column(name = "hypervisor_type")
42-
@Enumerated(value = EnumType.STRING)
42+
@Convert(converter = HypervisorTypeConverter.class)
4343
private HypervisorType hypervisorType;
4444

4545
@Column(name = "hypervisor_version")

engine/schema/src/main/java/com/cloud/storage/GuestOSHypervisorVO.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.UUID;
2121

2222
import javax.persistence.Column;
23+
import javax.persistence.Convert;
2324
import javax.persistence.Entity;
2425
import javax.persistence.GeneratedValue;
2526
import javax.persistence.GenerationType;
@@ -28,6 +29,7 @@
2829

2930
import com.cloud.hypervisor.Hypervisor;
3031
import com.cloud.utils.db.GenericDao;
32+
import org.apache.cloudstack.util.HypervisorTypeConverter;
3133

3234
@Entity
3335
@Table(name = "guest_os_hypervisor")
@@ -44,6 +46,7 @@ public class GuestOSHypervisorVO implements GuestOSHypervisor {
4446
String guestOsName;
4547

4648
@Column(name = "hypervisor_type")
49+
@Convert(converter = HypervisorTypeConverter.class)
4750
String hypervisorType;
4851

4952
@Column(name = "hypervisor_version")

0 commit comments

Comments
 (0)