Commit 56b5187a authored by Spiros Koulouzis's avatar Spiros Koulouzis

move interfaces

added SURE Simple qUeRy sErvice TOSCA swagger
implementing cloudstorm service for provisioner 
parent 403b8ddc
swagger: "2.0"
info:
description: "SURE Simple qUeRy sErvice TOSCA. "
version: "3.0.0"
title: "SURE TOSCA"
contact:
email: "S.Koulouzis@uva.nl"
license:
name: "Apache 2.0"
url: "http://www.apache.org/licenses/LICENSE-2.0.html"
basePath: "/sure_tosca"
schemes:
- "https"
- "http"
paths:
/tosca_template/validate:
get:
summary: "validate tosca template file"
description: ""
operationId: "validateToscaTemplate"
consumes:
- "multipart/form-data"
parameters:
- in: "formData"
name: "file"
type: file
description: "tosca Template description"
required: true
responses:
200:
description: "successful operation"
schema:
type: "string"
405:
description: "Invalid input"
/tosca_template/{id}/node_templates:
get:
summary: ""
description: ""
operationId: "getNodeTemplates"
produces:
- "application/json"
parameters:
- name: "id"
in: "path"
description: "ID of topolog template uplodaed"
required: true
type: "string"
- in: query
name: node_type
type: string
description: The node type to return
responses:
200:
description: "successful operation"
schema:
$ref: '#/definitions/ArrayOfNodeTemplate'
405:
description: "Invalid input"
/tosca_template/{id}/node_templates/type_name:
get:
summary: ""
description: ""
operationId: "getNodeTypeName"
produces:
- "application/json"
parameters:
- name: "id"
in: "path"
description: "ID of topolog template uplodaed"
required: true
type: "string"
- in: "body"
name: "body"
description: ""
required: true
schema:
$ref: '#/definitions/NodeTemplate'
responses:
200:
description: "successful operation"
schema:
type: "string"
405:
description: "Invalid input"
/tosca_template/{id}/node_templates/requirements:
get:
summary: ""
description: ""
operationId: "getNodeRequirements"
produces:
- "application/json"
parameters:
- name: "id"
in: "path"
description: "ID of topolog template uplodaed"
required: true
type: "string"
- in: "body"
name: "body"
description: ""
required: true
schema:
$ref: '#/definitions/NodeTemplate'
responses:
200:
description: "successful operation"
schema:
type: object
additionalProperties:
type: string
405:
description: "Invalid input"
/tosca_template/{id}/node_templates/parent_type_name:
get:
summary: ""
description: ""
operationId: "getParentTypeName"
produces:
- "application/json"
parameters:
- name: "id"
in: "path"
description: "ID of topolog template uplodaed"
required: true
type: "string"
- in: "body"
name: "body"
description: ""
required: true
schema:
$ref: '#/definitions/NodeTemplate'
responses:
200:
description: "successful operation"
schema:
type: string
405:
description: "Invalid input"
/tosca_template/{id}/node_templates/ancestors_requirements:
get:
summary: ""
description: ""
operationId: "getAncestorsRequirements"
produces:
- "application/json"
parameters:
- name: "id"
in: "path"
description: "ID of topolog template uplodaed"
required: true
type: "string"
- in: "body"
name: "body"
description: ""
required: true
schema:
$ref: '#/definitions/NodeTemplate'
responses:
200:
description: "successful operation"
schema:
type: object
additionalProperties:
type: string
405:
description: "Invalid input"
securityDefinitions:
drip_auth:
type: "oauth2"
authorizationUrl: "http://localhost/oauth/dialog"
flow: "implicit"
scopes:
write:ToscaTemplate: "modify topolog template in your account"
read:ToscaTemplate: "read your topolog template"
admin:User: "Grants access to admin operations"
write:Credentials: "modify cloud credentials in your account"
read:Credentials: "read your cloud credentials"
definitions:
ToscaTemplate:
type: "object"
properties:
tosca_definitions_version:
type: "string"
tosca_default_namespace:
type: "string"
template_name:
type: "string"
imports:
type: "array"
items:
type: object
additionalProperties:
type: string
repositories:
type: object
additionalProperties:
type: string
dsl_definitions:
type: object
additionalProperties:
type: string
node_types:
type: object
additionalProperties:
type: object
topology_template:
$ref: "#/definitions/TopologyTemplate"
relationship_types:
type: object
additionalProperties:
type: object
relationship_templates:
type: object
additionalProperties:
type: object
capability_types:
type: object
additionalProperties:
type: object
artifact_types:
type: object
additionalProperties:
type: object
data_types:
type: object
additionalProperties:
type: object
interface_types:
type: object
additionalProperties:
type: object
policy_types:
type: object
additionalProperties:
type: string
group_types:
type: object
additionalProperties:
type: object
description:
type: "string"
template_author:
type: "string"
TopologyTemplate:
type: "object"
properties:
description:
type: "string"
inputs:
type: "array"
items:
type: object
additionalProperties:
type: object
policies:
type: "array"
items:
type: object
additionalProperties:
type: object
outputs:
type: "array"
items:
type: object
additionalProperties:
type: object
node_templates:
type: object
additionalProperties:
type: object
relationship_templates:
type: object
additionalProperties:
type: object
groups:
type: object
additionalProperties:
type: object
substitution_mappings:
type: object
additionalProperties:
type: object
NodeTemplate:
type: "object"
properties:
name:
type: "string"
type:
type: "string"
requirements:
type: "array"
items:
type: object
additionalProperties:
type: object
artifacts:
type: object
additionalProperties:
type: object
properties:
type: object
additionalProperties:
type: object
interfaces:
type: object
additionalProperties:
type: object
capabilities:
type: object
additionalProperties:
type: object
workflows:
type: object
additionalProperties:
type: object
ArrayOfNodeTemplate:
type: "array"
items:
$ref: "#/definitions/NodeTemplate"
externalDocs:
description: "Find out more about DRIP"
url: "https://github.com/QCAPI-DRIP/DRIP-integration/wiki"
......@@ -32,40 +32,42 @@ import sun.reflect.generics.reflectiveObjects.NotImplementedException;
*/
public class TOSCAUtils {
public static List<Map<String, Object>> getVMsFromTopology(ToscaTemplate toscaTemplate) {
List<String> vmNames = getVMsNodeNamesFromTopology(toscaTemplate);
TopologyTemplate topologyTemplate = toscaTemplate.getTopologyTemplate();
Map<String, Object> nodeTemplates = topologyTemplate.getNodeTemplates();
List<Map<String, Object>> vmList = new ArrayList<>();
for (String vmName : vmNames) {
Map<String, Object> vm = (Map<String, Object>) nodeTemplates.get(vmName);
// Map<String, Object> properties = (Map<String, Object>) vm.get("properties");
vmList.add(vm);
public static List<Map.Entry> getNodes(ToscaTemplate toscaTemplate, String filterType, String filterValue) {
boolean byType = false;
boolean byName = false;
switch (filterType) {
case "type":
byType = true;
break;
case "name":
byName = true;
break;
}
return vmList;
}
public static List<String> getVMsNodeNamesFromTopology(ToscaTemplate toscaTemplate) {
TopologyTemplate topologyTemplate = toscaTemplate.getTopologyTemplate();
Map<String, Object> nodeTemplates = topologyTemplate.getNodeTemplates();
List<Map.Entry> nodeList = new ArrayList<>();
Iterator it = nodeTemplates.entrySet().iterator();
List<String> vmNames = new ArrayList<>();
while (it.hasNext()) {
Map.Entry node = (Map.Entry) it.next();
Map<String, Object> nodeValue = (Map<String, Object>) node.getValue();
if (byName && node.getKey().equals(filterValue)) {
nodeList.add(node);
}
if (byType) {
String type = (String) nodeValue.get("type");
if (type.equals("tosca.nodes.ARTICONF.VM.topology")) {
List<Map<String, Object>> requirements = (List<Map<String, Object>>) nodeValue.get("requirements");
for (Map<String, Object> req : requirements) {
Map.Entry<String, Object> requirementEntry = req.entrySet().iterator().next();
String nodeName = (String) ((Map<String, Object>) req.get(requirementEntry.getKey())).get("node");
vmNames.add(nodeName);
if (type.equals(filterValue)) {
nodeList.add(node);
}
}
}
return nodeList;
}
return vmNames;
public static List<Map.Entry> getNodesByType(ToscaTemplate toscaTemplate, String nodeTypeName) {
return getNodes(toscaTemplate, "type", nodeTypeName);
}
public static Map<String, Object> buildTOSCAOutput(Map<String, Object> outputs, String nodeName, String value, String key, boolean encodeValueToBas64) {
......@@ -90,7 +92,7 @@ public class TOSCAUtils {
List<Map<String, Object>> outputs = topologyTemplate.getOutputs();
List<Map<String, Object>> matchedOutputs = new ArrayList<>();
throw new NotImplementedException();
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
......@@ -255,4 +257,57 @@ public class TOSCAUtils {
containersList.add(container);
return containersList;
}
public static List<Map.Entry> getRelatedNodes(Map<String, Object> node, ToscaTemplate toscaTemplate) {
String nodeName = node.keySet().iterator().next();
Map<String, Object> nodeMap = (Map<String, Object>) node.get(nodeName);
if (nodeMap.containsKey("requirements")) {
List<String> nodeNames = new ArrayList<>();
List<Map<String, Object>> requirements = (List<Map<String, Object>>) nodeMap.get("requirements");
for (Map<String, Object> requirement : requirements) {
String reqName = requirement.keySet().iterator().next();
Map<String, Object> requirementMap = (Map<String, Object>) requirement.get(reqName);
// String requirementCapability = (String) requirementMap.get("capability");
String relatedNode = (String) requirementMap.get("node");
nodeNames.add(relatedNode);
}
List<Map.Entry> retaltedNodes = new ArrayList<>();
for (String name : nodeNames) {
List<Map.Entry> relatedNode = getNodesByName(toscaTemplate, name);
for (Map.Entry rNode : relatedNode) {
retaltedNodes.add(rNode);
}
}
return retaltedNodes;
}
return null;
}
private static List<Map.Entry> getNodesByName(ToscaTemplate toscaTemplate, String name) {
return getNodes(toscaTemplate, "name", name);
}
public static boolean nodeIsOfType(Map.Entry node, String type) {
String nodeName = (String) node.getKey();
Map<String, Object> nodeMap = (Map<String, Object>) node.getValue();
if (nodeMap.containsKey("type") && nodeMap.get("type").equals(type)) {
return true;
}
return false;
}
public static Object getNodeProperty(Map.Entry node, String propertyName) {
Map<String, Object> nodeMap = (Map<String, Object>) node.getValue();
if (nodeMap.containsKey("properties") ) {
Map<String, Object> properties = (Map<String, Object>) nodeMap.get("properties");
return properties.get(propertyName);
}
return null;
}
}
......@@ -38,7 +38,7 @@ public class ProvisionerService {
String ymlToscaTemplate = toscaTemplateService.findByID(id);
ToscaTemplate toscaTemplate = toscaTemplateService.getYaml2ToscaTemplate(ymlToscaTemplate);
TOSCAUtils.getVMsFromTopology(toscaTemplate);
TOSCAUtils.getNodesByType(toscaTemplate);
return null;
}
......
......@@ -37,6 +37,18 @@
<version>3.0.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
<type>jar</type>
</dependency>
</dependencies>
......
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package nl.uva.sne.drip.drip.provisioner;
package nl.uva.sne.drip.provisioner;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
......@@ -28,6 +28,7 @@ import java.util.concurrent.TimeoutException;
import java.util.logging.Level;
import java.util.logging.Logger;
import nl.uva.sne.drip.model.Message;
import nl.uva.sne.drip.model.ToscaTemplate;
/**
*
......@@ -66,7 +67,14 @@ public class Consumer extends DefaultConsumer {
throw new FileNotFoundException("Could not create input directory: " + tempInputDir.getAbsolutePath());
}
String response = objectMapper.writeValueAsString(message);
ProvisionerRPCService service = new ProvisionerRPCService();
ToscaTemplate toscaTemplate = service.execute(message.getToscaTemplate());
Message responceMessage = new Message();
responceMessage.setCreationDate(System.currentTimeMillis());
responceMessage.setToscaTemplate(toscaTemplate);
String response = objectMapper.writeValueAsString(responceMessage);
logger.log(Level.INFO, "Sending Response: '{'0'}'{0}", response);
// Logger.getLogger(Consumer.class.getName()).log(Level.INFO, "Sending Response: {0}", response);
......
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package nl.uva.sne.drip.provisioner;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.KeyPair;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import nl.uva.sne.drip.commons.utils.TOSCAUtils;
import nl.uva.sne.drip.model.ToscaTemplate;
import org.apache.commons.io.FilenameUtils;
/**
*
* @author S. Koulouzis
*/
class ProvisionerRPCService {
private List<Map.Entry> vmTopologies;
private String tempInputDirPath;
ToscaTemplate execute(ToscaTemplate toscaTemplate) throws FileNotFoundException, JSchException, IOException {
tempInputDirPath = System.getProperty("java.io.tmpdir") + File.separator + "Input-" + Long.toString(System.nanoTime()) + File.separator;
File tempInputDir = new File(tempInputDirPath);
if (!(tempInputDir.mkdirs())) {
throw new FileNotFoundException("Could not create input directory: " + tempInputDir.getAbsolutePath());
}
buildCloudStormTopTopology(toscaTemplate);
return toscaTemplate;
}
private Map<String, Object> buildCloudStormTopTopology(ToscaTemplate toscaTemplate) throws JSchException, IOException {
Map<String, Object> topTopology = new HashMap<>();
topTopology.put("userName", getVMsUSername(toscaTemplate));
String keysPath = buildSSHKeyPair();
topTopology.put("publicKeyPath", keysPath);
List<Map<String, Object>> subnets = new ArrayList<>();
int counter = 0;
for (Map.Entry vmTopology : getVmTopologies(toscaTemplate)) {
String subnetValue = getSubnets(vmTopology);
if (subnetValue != null) {
Map<String, Object> subnetMap = new HashMap<>();
subnetMap.put("name", "subnet" + counter++);
subnetMap.put("subnet", subnetValue.split("/")[0]);
subnetMap.put("netmask", subnetValue.split("/")[1]);
subnetMap.put("members", members);
subnets.add(subnetMap);
}
}
if (subnets != null) {
topTopology.put("subnets", subnets);
}
List<Map<String, Object>> subTopologies = buildCloudStormSubTopologies(toscaTemplate);
topTopology.put("topologies", subTopologies);
return topTopology;
}
private String getVMsUSername(ToscaTemplate toscaTemplate) {
List<Map.Entry> topologyVMs = getTopologyVMs(getVmTopologies(toscaTemplate).get(0), toscaTemplate);
return (String) TOSCAUtils.getNodeProperty(topologyVMs.get(0), "user_name");
}
private List<Map.Entry> getTopologyVMs(Map.Entry topology, ToscaTemplate toscaTemplate) {
List<Map.Entry> topologyVMs = new ArrayList<>();
Map<String, Object> topologyMap = new HashMap<>();
topologyMap.put((String) topology.getKey(), topology.getValue());
List<Map.Entry> relatedNodes = TOSCAUtils.getRelatedNodes(topologyMap, toscaTemplate);
for (Map.Entry node : relatedNodes) {
if (TOSCAUtils.nodeIsOfType(node, "tosca.nodes.ARTICONF.VM.Compute")) {
topologyVMs.add(node);
}
}
return topologyVMs;
}
private String buildSSHKeyPair() throws JSchException, IOException {
String userPublicKeyName = "id_rsa.pub";
String publicKeyPath = "name@" + userPublicKeyName;
JSch jsch = new JSch();
KeyPair kpair = KeyPair.genKeyPair(jsch, KeyPair.RSA);
String userPrivateName = FilenameUtils.removeExtension(userPublicKeyName);
kpair.writePrivateKey(tempInputDirPath + File.separator + userPrivateName);
kpair.writePublicKey(tempInputDirPath + File.separator + userPublicKeyName, "auto generated user accees keys");
kpair.dispose();
return publicKeyPath;
}
private String getSubnets(Map.Entry node) {
return (String) TOSCAUtils.getNodeProperty(node, "subnet");
}
/**
* @return the vmTopologies
*/
public List<Map.Entry> getVmTopologies(ToscaTemplate toscaTemplate) {
if (vmTopologies == null) {
vmTopologies = TOSCAUtils.getNodesByType(toscaTemplate, "tosca.nodes.ARTICONF.VM.topology");
}
return vmTopologies;
}
private List<Map<String, Object>> buildCloudStormSubTopologies(ToscaTemplate toscaTemplate) {
List<Map<String, Object>> cloudStormSubTopologies = new ArrayList<>();
for(Map.Entry topology: getVmTopologies(toscaTemplate)){
Map<String, Object> cloudStormSubTopology = new HashMap<>();
cloudStormSubTopology.put("topology", topology.getKey());
cloudStormSubTopology.put("cloudProvider", TOSCAUtils.getNodeProperty(topology, "provider"));
cloudStormSubTopology.put("domain", TOSCAUtils.getNodeProperty(topology, "domain"));
cloudStormSubTopology.put("status", TOSCAUtils.getNodeProperty(topology, "domain"));
}
return cloudStormSubTopologies;
}
}
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package nl.uva.sne.drip.drip.provisioner;
package nl.uva.sne.drip.provisioner;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
......@@ -70,7 +70,7 @@ public class RPCServer {
//We define the queue name
channel.queueDeclare(prop.getProperty("message.broker.queue.provisioner", "provisioner"), false, false, false, null);
DefaultConsumer c;
c = new nl.uva.sne.drip.drip.provisioner.Consumer(channel);
c = new nl.uva.sne.drip.provisioner.Consumer(channel);
//Start listening for messages
channel.basicConsume(prop.getProperty("message.broker.queue.provisioner", "provisioner"), false, c);
......
......@@ -2,6 +2,11 @@
<project version="4">
<component name="ChangeListManager">
<list default="true" id="462ede19-adfe-472b-975e-fefefa973fe0" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/../drip-commons/src/main/java/nl/uva/sne/drip/commons/utils/TOSCAUtils.java" beforeDir="false" afterPath="$PROJECT_DIR$/../drip-commons/src/main/java/nl/uva/sne/drip/commons/utils/TOSCAUtils.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../drip-manager/src/main/java/nl/uva/sne/drip/service/ProvisionerService.java" beforeDir="false" afterPath="$PROJECT_DIR$/../drip-manager/src/main/java/nl/uva/sne/drip/service/ProvisionerService.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../drip-manager/swagger.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/../drip-manager/swagger.yaml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../drip-provisioner/src/main/java/nl/uva/sne/drip/drip/provisioner/Consumer.java" beforeDir="false" afterPath="$PROJECT_DIR$/../drip-provisioner/src/main/java/nl/uva/sne/drip/provisioner/Consumer.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../drip-provisioner/src/main/java/nl/uva/sne/drip/drip/provisioner/RPCServer.java" beforeDir="false" afterPath="$PROJECT_DIR$/../drip-provisioner/src/main/java/nl/uva/sne/drip/provisioner/RPCServer.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
</list>
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
......@@ -325,11 +330,6 @@
<line>64</line>
<option name="timeStamp" value="1" />
</line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/src/utils/tosca.py</url>
<line>22</line>
<option name="timeStamp" value="128" />
</line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/src/rpc_server.py</url>
<line>106</line>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment