Skip to content

Commit b63e5f4

Browse files
continue implementation
1 parent 83474f6 commit b63e5f4

12 files changed

Lines changed: 180 additions & 99 deletions

File tree

plugins/iac/nimble/src/main/java/org/apache/cloudstack/service/NimbleManagerImpl.java

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,11 @@
2121
import org.apache.cloudstack.framework.config.ConfigKey;
2222
import org.apache.cloudstack.persistence.iactemplatesprofile.IacTemplatesProfile;
2323
import org.apache.cloudstack.persistence.iactemplatesprofile.IacTemplatesProfileDao;
24+
import org.apache.cloudstack.tosca.model.ToscaNodeType;
25+
import org.apache.cloudstack.tosca.parser.ToscaParser;
2426

2527
import javax.inject.Inject;
2628
import javax.naming.ConfigurationException;
27-
import java.io.IOException;
28-
import java.nio.file.Files;
29-
import java.nio.file.Path;
3029
import java.nio.file.Paths;
3130
import java.util.ArrayList;
3231
import java.util.List;
@@ -36,12 +35,15 @@
3635
import java.util.stream.Collectors;
3736

3837
public class NimbleManagerImpl extends ManagerBase implements NimbleService {
38+
@Inject
39+
private ToscaParser toscaParser;
40+
3941
@Inject
4042
private IacTemplatesProfileDao iacTemplatesProfileDao;
4143

4244
private ExecutorService nimbleExecutorPool;
4345

44-
private List<IacTemplatesProfile> toscaProfile;
46+
private Map<String, ToscaNodeType> toscaProfile;
4547

4648
@Override
4749
public void listIacResourceTypes() {
@@ -55,29 +57,17 @@ public boolean configure(String name, Map<String, Object> params) throws Configu
5557
int nimbleServicePoolSize = NimbleService.NimbleServicePoolSize.value();
5658
logger.debug("Configuring NIMBLE's fixed thread pool with [{}] threads.", nimbleServicePoolSize);
5759
nimbleExecutorPool = Executors.newFixedThreadPool(nimbleServicePoolSize);
58-
59-
loadToscaProfile();
60-
60+
toscaProfile = loadToscaProfile();
6161
return true;
6262
}
6363

64-
protected List<String> loadToscaProfile() {
64+
protected Map<String, ToscaNodeType> loadToscaProfile() {
6565
logger.info("Loading NIMBLE's TOSCA profile.");
6666
List<IacTemplatesProfile> profileElements = iacTemplatesProfileDao.listAll();
6767

68-
return profileElements.stream().map(element -> {
69-
String elementContent = getElementDefinition(element.getElementContentFilePath());
70-
return elementContent;
71-
}).collect(Collectors.toList());
72-
}
73-
74-
protected String getElementDefinition(String elementContentFilePath) {
75-
Path path = Paths.get(String.format("%s%s", NIMBLE_CONFIG_PATH, elementContentFilePath));
76-
try {
77-
return Files.readString(path);
78-
} catch (IOException e) {
79-
return null;
80-
}
68+
return profileElements.stream()
69+
.map(element -> toscaParser.parseNodeType(Paths.get(String.format("%s/%s", NIMBLE_PROFILE_FOLDER_PATH, element.getElementContentFilePath()))))
70+
.collect(Collectors.toMap(ToscaNodeType::getName, nodeType -> nodeType));
8171
}
8272

8373
@Override

plugins/iac/nimble/src/main/java/org/apache/cloudstack/service/NimbleService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import org.apache.cloudstack.framework.config.Configurable;
2222

2323
public interface NimbleService extends PluggableService, Configurable {
24-
String NIMBLE_CONFIG_PATH = "/usr/share/cloudstack-management/nimble/";
24+
String NIMBLE_PROFILE_FOLDER_PATH = "/usr/share/cloudstack-management/nimble/profile";
2525

2626
ConfigKey<Boolean> NimbleServiceEnabled = new ConfigKey<>("Advanced", Boolean.class,
2727
"nimble.service.enabled", "false",

plugins/iac/nimble/src/main/java/org/apache/cloudstack/tosca/ToscaParser.java

Lines changed: 0 additions & 13 deletions
This file was deleted.

plugins/iac/nimble/src/main/java/org/apache/cloudstack/tosca/loader/ToscaYamlLoader.java

Lines changed: 0 additions & 34 deletions
This file was deleted.

plugins/iac/nimble/src/main/java/org/apache/cloudstack/tosca/loader/YamlUtils.java

Lines changed: 0 additions & 30 deletions
This file was deleted.

plugins/iac/nimble/src/main/java/org/apache/cloudstack/tosca/model/ToscaAttributeDefinition.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,9 @@ public class ToscaAttributeDefinition extends ToscaFieldDefinition {
44
public ToscaAttributeDefinition(String name, String description, ToscaPrimitiveType type) {
55
super(name, description, type);
66
}
7+
8+
@Override
9+
public String toString() {
10+
return String.format("%s: %s", this.getClass().getName(), super.toString());
11+
}
712
}

plugins/iac/nimble/src/main/java/org/apache/cloudstack/tosca/model/ToscaFieldDefinition.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.apache.cloudstack.tosca.model;
22

3+
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
4+
35
public abstract class ToscaFieldDefinition {
46
private String name;
57
private String description;
@@ -22,4 +24,9 @@ public String getDescription() {
2224
public ToscaPrimitiveType getType() {
2325
return type;
2426
}
27+
28+
@Override
29+
public String toString() {
30+
return ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, "name", "description", "type");
31+
}
2532
}

plugins/iac/nimble/src/main/java/org/apache/cloudstack/tosca/model/ToscaNodeType.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.apache.cloudstack.tosca.model;
22

3+
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
4+
35
import java.util.Map;
46

57
public class ToscaNodeType {
@@ -24,4 +26,9 @@ public Map<String, ToscaPropertyDefinition> getProperties() {
2426
public Map<String, ToscaAttributeDefinition> getAttributes() {
2527
return attributes;
2628
}
29+
30+
@Override
31+
public String toString() {
32+
return ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, "name", "properties", "attributes");
33+
}
2734
}

plugins/iac/nimble/src/main/java/org/apache/cloudstack/tosca/model/ToscaPropertyDefinition.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,9 @@ public boolean isRequired() {
1717
public Object getValidation() {
1818
return validation;
1919
}
20+
21+
@Override
22+
public String toString() {
23+
return String.format("%s: %s", this.getClass().getName(), super.toString());
24+
}
2025
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
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.tosca.parser;
18+
19+
import org.apache.cloudstack.tosca.model.ToscaAttributeDefinition;
20+
import org.apache.cloudstack.tosca.model.ToscaFieldDefinition;
21+
import org.apache.cloudstack.tosca.model.ToscaNodeType;
22+
import org.apache.cloudstack.tosca.model.ToscaPrimitiveType;
23+
import org.apache.cloudstack.tosca.model.ToscaPropertyDefinition;
24+
import org.apache.commons.lang3.BooleanUtils;
25+
import org.apache.commons.lang3.EnumUtils;
26+
import org.apache.logging.log4j.LogManager;
27+
import org.apache.logging.log4j.Logger;
28+
29+
import java.nio.file.Path;
30+
import java.util.Map;
31+
import java.util.Optional;
32+
import java.util.stream.Collectors;
33+
34+
public class ToscaParser {
35+
private Logger logger = LogManager.getLogger(ToscaParser.class);
36+
37+
enum FieldDefinitionType {
38+
ATTRIBUTE, PROPERTY
39+
}
40+
41+
private static final String NODE_TYPES_KEY = "node_types";
42+
private static final String NODE_TYPES_PROPERTIES_KEY = "properties";
43+
private static final String NODE_TYPES_ATTRIBUTES_KEY = "attributes";
44+
45+
@SuppressWarnings("unchecked")
46+
public ToscaNodeType parseNodeType(Path path) {
47+
Object rawYaml = ToscaYamlHelper.loadYaml(path);
48+
Map<String, Object> yamlRoot = ToscaYamlHelper.asMap(rawYaml);
49+
logger.debug("Trying to extract only one node type from the [{}] file, since it is expected for each node type to be declared separately.", path);
50+
Optional<Map.Entry<String, Object>> nodeTypeRaw = ToscaYamlHelper.asMap(yamlRoot.get(NODE_TYPES_KEY)).entrySet().stream().findFirst();
51+
if (nodeTypeRaw.isEmpty()) {
52+
logger.error("No node types are declared in [{}].", path);
53+
return null;
54+
}
55+
String nodeTypeName = nodeTypeRaw.get().getKey();
56+
logger.debug("Parsing the following node type: [{}].", nodeTypeName);
57+
Map<String, Object> nodeTypeBody = ToscaYamlHelper.asMap(nodeTypeRaw.get().getValue());
58+
Map<String, ToscaPropertyDefinition> propertyDefinitions = (Map<String, ToscaPropertyDefinition>) parseFieldDefinition(nodeTypeBody.get(NODE_TYPES_PROPERTIES_KEY), FieldDefinitionType.PROPERTY);
59+
Map<String, ToscaAttributeDefinition> attributeDefinitions = (Map<String, ToscaAttributeDefinition>) parseFieldDefinition(nodeTypeBody.get(NODE_TYPES_ATTRIBUTES_KEY), FieldDefinitionType.ATTRIBUTE);
60+
ToscaNodeType nodeType = new ToscaNodeType(nodeTypeName, propertyDefinitions, attributeDefinitions);
61+
logger.info("Successfully parsed the following node type: [{}].", nodeType::toString);
62+
return nodeType;
63+
}
64+
65+
private Map<String, ? extends ToscaFieldDefinition> parseFieldDefinition(Object rawFields, FieldDefinitionType fieldDefinitionType) {
66+
Map<String, Object> fields = ToscaYamlHelper.asMap(rawFields);
67+
logger.debug("Parsing the following {}: [{}].",
68+
() -> fieldDefinitionType == FieldDefinitionType.ATTRIBUTE ? "attributes" : "properties", fields::keySet);
69+
70+
return fields.entrySet().stream().map((field) -> {
71+
String fieldName = field.getKey();
72+
Map<String, Object> fieldBody = ToscaYamlHelper.asMap(field.getValue());
73+
ToscaPrimitiveType fieldType = EnumUtils.getEnumIgnoreCase(ToscaPrimitiveType.class, ToscaYamlHelper.asString(fieldBody.get("type")));
74+
String propertyDescription = ToscaYamlHelper.asString(fieldBody.get("description"));
75+
76+
if (fieldDefinitionType == FieldDefinitionType.PROPERTY) {
77+
ToscaAttributeDefinition attributeDefinition = new ToscaAttributeDefinition(fieldName, propertyDescription, fieldType);
78+
logger.debug("Successfully parsed the following property: [{}].", attributeDefinition::toString);
79+
return attributeDefinition;
80+
}
81+
82+
boolean required = BooleanUtils.toBoolean(ToscaYamlHelper.asString(fieldBody.get("required")));
83+
Object validation = fieldBody.get("validation");
84+
ToscaPropertyDefinition propertyDefinition = new ToscaPropertyDefinition(fieldName, propertyDescription, fieldType, required, validation);;
85+
logger.debug("Successfully parsed the following property: [{}].", propertyDefinition::toString);
86+
return propertyDefinition;
87+
}).collect(Collectors.toMap(ToscaFieldDefinition::getName, (field) -> field));
88+
}
89+
}

0 commit comments

Comments
 (0)