diff options
author | Dan Timoney <dtimoney@att.com> | 2017-02-15 15:27:41 -0500 |
---|---|---|
committer | Dan Timoney <dtimoney@att.com> | 2017-02-15 15:28:46 -0500 |
commit | 2750f8c09a37c7cd5ff8678b3d0e5f7dac687376 (patch) | |
tree | c77c01c58f326c11434c03a76b34b21a99b5fd70 /restapi-call-node/provider/src/main | |
parent | ed6b164bda6903ccfbd487f8c52a53bdf046ffd7 (diff) |
Initial commit for OpenECOMP SDN-C plugins
Change-Id: I0deb50b4f047c419181bb8c9e4df09c67495aa79
Signed-off-by: Dan Timoney <dtimoney@att.com>
Diffstat (limited to 'restapi-call-node/provider/src/main')
18 files changed, 1868 insertions, 0 deletions
diff --git a/restapi-call-node/provider/src/main/java/org/openecomp/sdnc/restapicall/JsonParser.java b/restapi-call-node/provider/src/main/java/org/openecomp/sdnc/restapicall/JsonParser.java new file mode 100644 index 0000000..c03191a --- /dev/null +++ b/restapi-call-node/provider/src/main/java/org/openecomp/sdnc/restapicall/JsonParser.java @@ -0,0 +1,85 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdnc.restapicall; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.codehaus.jettison.json.JSONArray; +import org.codehaus.jettison.json.JSONException; +import org.codehaus.jettison.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class JsonParser { + + private static final Logger log = LoggerFactory.getLogger(JsonParser.class); + + @SuppressWarnings("unchecked") + public static Map<String, String> convertToProperties(String s) throws JSONException { + JSONObject json = new JSONObject(s); + + Map<String, Object> wm = new HashMap<String, Object>(); + Iterator<String> ii = json.keys(); + while (ii.hasNext()) { + String key1 = ii.next(); + wm.put(key1, json.get(key1)); + } + + Map<String, String> mm = new HashMap<String, String>(); + + while (!wm.isEmpty()) + for (String key : new ArrayList<>(wm.keySet())) { + Object o = wm.get(key); + wm.remove(key); + + if (o instanceof Boolean || o instanceof Number || o instanceof String) { + mm.put(key, o.toString()); + + log.info("Added property: " + key + ": " + o.toString()); + } + + else if (o instanceof JSONObject) { + JSONObject jo = (JSONObject) o; + Iterator<String> i = jo.keys(); + while (i.hasNext()) { + String key1 = i.next(); + wm.put(key + "." + key1, jo.get(key1)); + } + } + + else if (o instanceof JSONArray) { + JSONArray ja = (JSONArray) o; + mm.put(key + "_length", String.valueOf(ja.length())); + + log.info("Added property: " + key + "_length" + ": " + String.valueOf(ja.length())); + + for (int i = 0; i < ja.length(); i++) + wm.put(key + '[' + i + ']', ja.get(i)); + } + } + + return mm; + } +} diff --git a/restapi-call-node/provider/src/main/java/org/openecomp/sdnc/restapicall/RestapiCallNode.java b/restapi-call-node/provider/src/main/java/org/openecomp/sdnc/restapicall/RestapiCallNode.java new file mode 100644 index 0000000..d6d3529 --- /dev/null +++ b/restapi-call-node/provider/src/main/java/org/openecomp/sdnc/restapicall/RestapiCallNode.java @@ -0,0 +1,701 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdnc.restapicall; + +import java.io.FileInputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.KeyStore; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.ws.rs.core.EntityTag; +import javax.ws.rs.core.MultivaluedMap; + +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicException; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.api.client.config.ClientConfig; +import com.sun.jersey.api.client.config.DefaultClientConfig; +import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter; +import com.sun.jersey.client.urlconnection.HTTPSProperties; + +public class RestapiCallNode implements SvcLogicJavaPlugin { + + private static final Logger log = LoggerFactory.getLogger(RestapiCallNode.class); + + private String uebServers; + private String defaultUebTemplateFileName = "/opt/bvc/restapi/templates/default-ueb-message.json"; + + public void sendRequest(Map<String, String> paramMap, SvcLogicContext ctx) throws SvcLogicException { + HttpResponse r = null; + try { + Param p = getParameters(paramMap); + + String pp = p.responsePrefix != null ? p.responsePrefix + '.' : ""; + + String req = null; + if (p.templateFileName != null) { + String reqTemplate = readFile(p.templateFileName); + req = buildXmlJsonRequest(ctx, reqTemplate, p.format); + } + r = sendHttpRequest(req, p); + setResponseStatus(ctx, p.responsePrefix, r); + + if (r.body != null && r.body.trim().length() > 0) { + ctx.setAttribute(pp + "httpResponse", r.body); + + if (p.convertResponse) { + Map<String, String> mm = null; + if (p.format == Format.XML) + mm = XmlParser.convertToProperties(r.body, p.listNameList); + else if (p.format == Format.JSON) + mm = JsonParser.convertToProperties(r.body); + + if (mm != null) + for (String key : mm.keySet()) + ctx.setAttribute(pp + key, mm.get(key)); + } + } + } catch (Exception e) { + log.error("Error sending the request: " + e.getMessage(), e); + + r = new HttpResponse(); + r.code = 500; + r.message = e.getMessage(); + String prefix = parseParam(paramMap, "responsePrefix", false, null); + setResponseStatus(ctx, prefix, r); + } + + if (r != null && r.code >= 300) + throw new SvcLogicException(String.valueOf(r.code) + ": " + r.message); + } + + private Param getParameters(Map<String, String> paramMap) throws SvcLogicException { + Param p = new Param(); + p.templateFileName = parseParam(paramMap, "templateFileName", false, null); + p.restapiUrl = parseParam(paramMap, "restapiUrl", true, null); + p.restapiUser = parseParam(paramMap, "restapiUser", true, null); + p.restapiPassword = parseParam(paramMap, "restapiPassword", true, null); + p.format = Format.fromString(parseParam(paramMap, "format", false, "json")); + p.httpMethod = HttpMethod.fromString(parseParam(paramMap, "httpMethod", false, "post")); + p.responsePrefix = parseParam(paramMap, "responsePrefix", false, null); + p.listNameList = getListNameList(paramMap); + String skipSendingStr = paramMap.get("skipSending"); + p.skipSending = skipSendingStr != null && skipSendingStr.equalsIgnoreCase("true"); + p.convertResponse = Boolean.valueOf(parseParam(paramMap, "convertResponse", false, "true")); + p.trustStoreFileName = parseParam(paramMap, "trustStoreFileName", false, null); + p.trustStorePassword = parseParam(paramMap, "trustStorePassword", false, null); + p.keyStoreFileName = parseParam(paramMap, "keyStoreFileName", false, null); + p.keyStorePassword = parseParam(paramMap, "keyStorePassword", false, null); + p.ssl = p.trustStoreFileName != null && p.trustStorePassword != null && p.keyStoreFileName != null && + p.keyStorePassword != null; + return p; + } + + private Set<String> getListNameList(Map<String, String> paramMap) { + Set<String> ll = new HashSet<String>(); + for (String key : paramMap.keySet()) + if (key.startsWith("listName")) + ll.add(paramMap.get(key)); + return ll; + } + + private String parseParam(Map<String, String> paramMap, String name, boolean required, String def) + throws SvcLogicException { + String s = paramMap.get(name); + + if (s == null || s.trim().length() == 0) { + if (!required) + return def; + throw new SvcLogicException("Parameter " + name + " is required in RestapiCallNode"); + } + + s = s.trim(); + String value = ""; + int i = 0; + int i1 = s.indexOf('%'); + while (i1 >= 0) { + int i2 = s.indexOf('%', i1 + 1); + if (i2 < 0) + break; + + String varName = s.substring(i1 + 1, i2); + String varValue = System.getenv(varName); + if (varValue == null) + varValue = "%" + varName + "%"; + + value += s.substring(i, i1); + value += varValue; + + i = i2 + 1; + i1 = s.indexOf('%', i); + } + value += s.substring(i); + + log.info("Parameter " + name + ": [" + value + "]"); + return value; + } + + private static class Param { + + public String templateFileName; + public String restapiUrl; + public String restapiUser; + public String restapiPassword; + public Format format; + public HttpMethod httpMethod; + public String responsePrefix; + public Set<String> listNameList; + public boolean skipSending; + public boolean convertResponse; + public String keyStoreFileName; + public String keyStorePassword; + public String trustStoreFileName; + public String trustStorePassword; + public boolean ssl; + } + + private static enum Format { + JSON, XML; + + public static Format fromString(String s) { + if (s == null) + return null; + if (s.equalsIgnoreCase("json")) + return JSON; + if (s.equalsIgnoreCase("xml")) + return XML; + throw new IllegalArgumentException("Invalid value for format: " + s); + } + } + + private static enum HttpMethod { + GET, POST, PUT, DELETE; + + public static HttpMethod fromString(String s) { + if (s == null) + return null; + if (s.equalsIgnoreCase("get")) + return GET; + if (s.equalsIgnoreCase("post")) + return POST; + if (s.equalsIgnoreCase("put")) + return PUT; + if (s.equalsIgnoreCase("delete")) + return DELETE; + throw new IllegalArgumentException("Invalid value for HTTP Method: " + s); + } + } + + private String buildXmlJsonRequest(SvcLogicContext ctx, String template, Format format) { + log.info("Building " + format + " started"); + long t1 = System.currentTimeMillis(); + + template = expandRepeats(ctx, template, 1); + + Map<String, String> mm = new HashMap<>(); + for (String s : ctx.getAttributeKeySet()) + mm.put(s, ctx.getAttribute(s)); + + StringBuilder ss = new StringBuilder(); + int i = 0; + while (i < template.length()) { + int i1 = template.indexOf("${", i); + if (i1 < 0) { + ss.append(template.substring(i)); + break; + } + + int i2 = template.indexOf('}', i1 + 2); + if (i2 < 0) + throw new RuntimeException("Template error: Matching } not found"); + + String var1 = template.substring(i1 + 2, i2); + String value1 = format == Format.XML ? XmlJsonUtil.getXml(mm, var1) : XmlJsonUtil.getJson(mm, var1); + // log.info(" " + var1 + ": " + value1); + if (value1 == null || value1.trim().length() == 0) { + // delete the whole element (line) + int i3 = template.lastIndexOf('\n', i1); + if (i3 < 0) + i3 = 0; + int i4 = template.indexOf('\n', i1); + if (i4 < 0) + i4 = template.length(); + + if (i < i3) + ss.append(template.substring(i, i3)); + i = i4; + } else { + ss.append(template.substring(i, i1)).append(value1); + i = i2 + 1; + } + } + + String req = format == Format.XML + ? XmlJsonUtil.removeEmptyStructXml(ss.toString()) : XmlJsonUtil.removeEmptyStructJson(ss.toString()); + + if (format == Format.JSON) + req = XmlJsonUtil.removeLastCommaJson(req); + + long t2 = System.currentTimeMillis(); + log.info("Building " + format + " completed. Time: " + (t2 - t1)); + + return req; + } + + private String expandRepeats(SvcLogicContext ctx, String template, int level) { + StringBuilder newTemplate = new StringBuilder(); + int k = 0; + while (k < template.length()) { + int i1 = template.indexOf("${repeat:", k); + if (i1 < 0) { + newTemplate.append(template.substring(k)); + break; + } + + int i2 = template.indexOf(':', i1 + 9); + if (i2 < 0) + throw new RuntimeException( + "Template error: Context variable name followed by : is required after repeat"); + + // Find the closing }, store in i3 + int nn = 1; + int i3 = -1; + int i = i2; + while (nn > 0 && i < template.length()) { + i3 = template.indexOf('}', i); + if (i3 < 0) + throw new RuntimeException("Template error: Matching } not found"); + int i32 = template.indexOf('{', i); + if (i32 >= 0 && i32 < i3) { + nn++; + i = i32 + 1; + } else { + nn--; + i = i3 + 1; + } + } + + String var1 = template.substring(i1 + 9, i2); + String value1 = ctx.getAttribute(var1); + log.info(" " + var1 + ": " + value1); + int n = 0; + try { + n = Integer.parseInt(value1); + } catch (Exception e) { + n = 0; + } + + newTemplate.append(template.substring(k, i1)); + + String rpt = template.substring(i2 + 1, i3); + + for (int ii = 0; ii < n; ii++) { + String ss = rpt.replaceAll("\\[\\$\\{" + level + "\\}\\]", "[" + ii + "]"); + if (ii == n - 1 && ss.trim().endsWith(",")) { + int i4 = ss.lastIndexOf(','); + if (i4 > 0) + ss = ss.substring(0, i4) + ss.substring(i4 + 1); + } + newTemplate.append(ss); + } + + k = i3 + 1; + } + + if (k == 0) + return newTemplate.toString(); + + return expandRepeats(ctx, newTemplate.toString(), level + 1); + } + + private String readFile(String fileName) throws Exception { + byte[] encoded = Files.readAllBytes(Paths.get(fileName)); + return new String(encoded, "UTF-8"); + } + + private HttpResponse sendHttpRequest(String request, Param p) throws Exception { + ClientConfig config = new DefaultClientConfig(); + SSLContext ssl = null; + if (p.ssl && p.restapiUrl.startsWith("https")) + ssl = createSSLContext(p); + if (ssl != null) { + HostnameVerifier hostnameVerifier = new HostnameVerifier() { + + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + }; + + config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, + new HTTPSProperties(hostnameVerifier, ssl)); + } + + logProperties(config.getProperties()); + + Client client = Client.create(config); + client.setConnectTimeout(5000); + client.addFilter(new HTTPBasicAuthFilter(p.restapiUser, p.restapiPassword)); + WebResource webResource = client.resource(p.restapiUrl); + + log.info("Sending request:"); + log.info(request); + long t1 = System.currentTimeMillis(); + + HttpResponse r = new HttpResponse(); + r.code = 200; + + if (!p.skipSending) { + String tt = p.format == Format.XML ? "application/xml" : "application/json"; + String tt1 = tt + ";charset=UTF-8"; + + ClientResponse response = null; + if (p.httpMethod == HttpMethod.GET) + response = webResource.accept(tt).type(tt1).get(ClientResponse.class); + else if (p.httpMethod == HttpMethod.POST) + response = webResource.accept(tt).type(tt1).post(ClientResponse.class, request); + else if (p.httpMethod == HttpMethod.PUT) + response = webResource.accept(tt).type(tt1).put(ClientResponse.class, request); + else if (p.httpMethod == HttpMethod.DELETE) + response = webResource.accept(tt).type(tt1).delete(ClientResponse.class, request); + + r.code = response.getStatus(); + r.headers = response.getHeaders(); + EntityTag etag = response.getEntityTag(); + if (etag != null) + r.message = etag.getValue(); + if (response.hasEntity() && r.code != 204) + r.body = response.getEntity(String.class); + } + + long t2 = System.currentTimeMillis(); + log.info("Response received. Time: " + (t2 - t1)); + log.info("HTTP response code: " + r.code); + log.info("HTTP response message: " + r.message); + logHeaders(r.headers); + log.info("HTTP response: " + r.body); + + return r; + } + + private SSLContext createSSLContext(Param p) { + try { + System.setProperty("jsse.enableSNIExtension", "false"); + System.setProperty("javax.net.ssl.trustStore", p.trustStoreFileName); + System.setProperty("javax.net.ssl.trustStorePassword", p.trustStorePassword); + + HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { + + @Override + public boolean verify(String string, SSLSession ssls) { + return true; + } + }); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + FileInputStream in = new FileInputStream(p.keyStoreFileName); + KeyStore ks = KeyStore.getInstance("PKCS12"); + char[] pwd = p.keyStorePassword.toCharArray(); + ks.load(in, pwd); + kmf.init(ks, pwd); + + SSLContext ctx = SSLContext.getInstance("TLS"); + ctx.init(kmf.getKeyManagers(), null, null); + return ctx; + } catch (Exception e) { + log.error("Error creating SSLContext: " + e.getMessage(), e); + } + return null; + } + + private static class HttpResponse { + + public int code; + public String message; + public String body; + public MultivaluedMap<String, String> headers; + } + + private void setResponseStatus(SvcLogicContext ctx, String prefix, HttpResponse r) { + String pp = prefix != null ? prefix + '.' : ""; + ctx.setAttribute(pp + "response-code", String.valueOf(r.code)); + ctx.setAttribute(pp + "response-message", r.message); + } + + public void sendFile(Map<String, String> paramMap, SvcLogicContext ctx) throws SvcLogicException { + HttpResponse r = null; + try { + FileParam p = getFileParameters(paramMap); + byte[] data = Files.readAllBytes(Paths.get(p.fileName)); + + r = sendHttpData(data, p); + setResponseStatus(ctx, p.responsePrefix, r); + + } catch (Exception e) { + log.error("Error sending the request: " + e.getMessage(), e); + + r = new HttpResponse(); + r.code = 500; + r.message = e.getMessage(); + String prefix = parseParam(paramMap, "responsePrefix", false, null); + setResponseStatus(ctx, prefix, r); + } + + if (r != null && r.code >= 300) + throw new SvcLogicException(String.valueOf(r.code) + ": " + r.message); + } + + private static class FileParam { + + public String fileName; + public String url; + public String user; + public String password; + public HttpMethod httpMethod; + public String responsePrefix; + public boolean skipSending; + } + + private FileParam getFileParameters(Map<String, String> paramMap) throws SvcLogicException { + FileParam p = new FileParam(); + p.fileName = parseParam(paramMap, "fileName", true, null); + p.url = parseParam(paramMap, "url", true, null); + p.user = parseParam(paramMap, "user", true, null); + p.password = parseParam(paramMap, "password", true, null); + p.httpMethod = HttpMethod.fromString(parseParam(paramMap, "httpMethod", false, "post")); + p.responsePrefix = parseParam(paramMap, "responsePrefix", false, null); + String skipSendingStr = paramMap.get("skipSending"); + p.skipSending = skipSendingStr != null && skipSendingStr.equalsIgnoreCase("true"); + return p; + } + + private HttpResponse sendHttpData(byte[] data, FileParam p) { + Client client = Client.create(); + client.setConnectTimeout(5000); + client.setFollowRedirects(true); + client.addFilter(new HTTPBasicAuthFilter(p.user, p.password)); + WebResource webResource = client.resource(p.url); + + log.info("Sending file"); + long t1 = System.currentTimeMillis(); + + HttpResponse r = new HttpResponse(); + r.code = 200; + + if (!p.skipSending) { + String tt = "application/octet-stream"; + + ClientResponse response = null; + if (p.httpMethod == HttpMethod.POST) + response = webResource.accept(tt).type(tt).post(ClientResponse.class, data); + else if (p.httpMethod == HttpMethod.PUT) + response = webResource.accept(tt).type(tt).put(ClientResponse.class, data); + + r.code = response.getStatus(); + r.headers = response.getHeaders(); + EntityTag etag = response.getEntityTag(); + if (etag != null) + r.message = etag.getValue(); + if (response.hasEntity() && r.code != 204) + r.body = response.getEntity(String.class); + + if (r.code == 301) { + String newUrl = response.getHeaders().getFirst("Location"); + + log.info("Got response code 301. Sending same request to URL: " + newUrl); + + webResource = client.resource(newUrl); + + if (p.httpMethod == HttpMethod.POST) + response = webResource.accept(tt).type(tt).post(ClientResponse.class, data); + else if (p.httpMethod == HttpMethod.PUT) + response = webResource.accept(tt).type(tt).put(ClientResponse.class, data); + + r.code = response.getStatus(); + etag = response.getEntityTag(); + if (etag != null) + r.message = etag.getValue(); + if (response.hasEntity() && r.code != 204) + r.body = response.getEntity(String.class); + } + } + + long t2 = System.currentTimeMillis(); + log.info("Response received. Time: " + (t2 - t1)); + log.info("HTTP response code: " + r.code); + log.info("HTTP response message: " + r.message); + logHeaders(r.headers); + log.info("HTTP response: " + r.body); + + return r; + } + + public void postMessageOnUeb(Map<String, String> paramMap, SvcLogicContext ctx) throws SvcLogicException { + HttpResponse r = null; + try { + UebParam p = getUebParameters(paramMap); + + String pp = p.responsePrefix != null ? p.responsePrefix + '.' : ""; + + String req = null; + + if (p.templateFileName == null) { + log.info("No template file name specified. Using default UEB template: " + defaultUebTemplateFileName); + p.templateFileName = defaultUebTemplateFileName; + } + + String reqTemplate = readFile(p.templateFileName); + reqTemplate = reqTemplate.replaceAll("rootVarName", p.rootVarName); + req = buildXmlJsonRequest(ctx, reqTemplate, Format.JSON); + + r = postOnUeb(req, p); + setResponseStatus(ctx, p.responsePrefix, r); + if (r.body != null) + ctx.setAttribute(pp + "httpResponse", r.body); + + } catch (Exception e) { + log.error("Error sending the request: " + e.getMessage(), e); + + r = new HttpResponse(); + r.code = 500; + r.message = e.getMessage(); + String prefix = parseParam(paramMap, "responsePrefix", false, null); + setResponseStatus(ctx, prefix, r); + } + + if (r != null && r.code >= 300) + throw new SvcLogicException(String.valueOf(r.code) + ": " + r.message); + } + + private static class UebParam { + + public String topic; + public String templateFileName; + public String rootVarName; + public String responsePrefix; + public boolean skipSending; + } + + private UebParam getUebParameters(Map<String, String> paramMap) throws SvcLogicException { + UebParam p = new UebParam(); + p.topic = parseParam(paramMap, "topic", true, null); + p.templateFileName = parseParam(paramMap, "templateFileName", false, null); + p.rootVarName = parseParam(paramMap, "rootVarName", false, null); + p.responsePrefix = parseParam(paramMap, "responsePrefix", false, null); + String skipSendingStr = paramMap.get("skipSending"); + p.skipSending = skipSendingStr != null && skipSendingStr.equalsIgnoreCase("true"); + return p; + } + + private HttpResponse postOnUeb(String request, UebParam p) throws Exception { + String[] urls = uebServers.split(" "); + for (int i = 0; i < urls.length; i++) { + if (!urls[i].endsWith("/")) + urls[i] += "/"; + urls[i] += "events/" + p.topic; + } + + Client client = Client.create(); + client.setConnectTimeout(5000); + WebResource webResource = client.resource(urls[0]); + + log.info("UEB URL: " + urls[0]); + log.info("Sending request:"); + log.info(request); + long t1 = System.currentTimeMillis(); + + HttpResponse r = new HttpResponse(); + r.code = 200; + + if (!p.skipSending) { + String tt = "application/json"; + String tt1 = tt + ";charset=UTF-8"; + + ClientResponse response = webResource.accept(tt).type(tt1).post(ClientResponse.class, request); + + r.code = response.getStatus(); + r.headers = response.getHeaders(); + if (response.hasEntity()) + r.body = response.getEntity(String.class); + } + + long t2 = System.currentTimeMillis(); + log.info("Response received. Time: " + (t2 - t1)); + log.info("HTTP response code: " + r.code); + logHeaders(r.headers); + log.info("HTTP response:\n" + r.body); + + return r; + } + + private void logProperties(Map<String, Object> mm) { + List<String> ll = new ArrayList<>(); + for (Object o : mm.keySet()) + ll.add((String) o); + Collections.sort(ll); + + log.info("Properties:"); + for (String name : ll) + log.info("--- " + name + ": " + String.valueOf(mm.get(name))); + } + + private void logHeaders(MultivaluedMap<String, String> mm) { + log.info("HTTP response headers:"); + + if (mm == null) + return; + + List<String> ll = new ArrayList<>(); + for (Object o : mm.keySet()) + ll.add((String) o); + Collections.sort(ll); + + for (String name : ll) + log.info("--- " + name + ": " + String.valueOf(mm.get(name))); + } + + public void setUebServers(String uebServers) { + this.uebServers = uebServers; + } + + public void setDefaultUebTemplateFileName(String defaultUebTemplateFileName) { + this.defaultUebTemplateFileName = defaultUebTemplateFileName; + } +} diff --git a/restapi-call-node/provider/src/main/java/org/openecomp/sdnc/restapicall/XmlJsonUtil.java b/restapi-call-node/provider/src/main/java/org/openecomp/sdnc/restapicall/XmlJsonUtil.java new file mode 100644 index 0000000..85175c3 --- /dev/null +++ b/restapi-call-node/provider/src/main/java/org/openecomp/sdnc/restapicall/XmlJsonUtil.java @@ -0,0 +1,372 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdnc.restapicall; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class XmlJsonUtil { + + private static final Logger log = LoggerFactory.getLogger(XmlJsonUtil.class); + + public static String getXml(Map<String, String> varmap, String var) { + boolean escape = true; + if (var.startsWith("'")) { + var = var.substring(1); + escape = false; + } + + Object o = createStructure(varmap, var); + return generateXml(o, 0, escape); + } + + public static String getJson(Map<String, String> varmap, String var) { + boolean escape = true; + if (var.startsWith("'")) { + var = var.substring(1); + escape = false; + } + + Object o = createStructure(varmap, var); + return generateJson(o, escape); + } + + private static Object createStructure(Map<String, String> flatmap, String var) { + if (flatmap.containsKey(var)) { + if (var.endsWith("_length") || var.endsWith("].key")) + return null; + return flatmap.get(var); + } + + Map<String, Object> mm = new HashMap<>(); + for (String k : flatmap.keySet()) + if (k.startsWith(var + ".")) { + int i1 = k.indexOf('.', var.length() + 1); + int i2 = k.indexOf('[', var.length() + 1); + int i3 = k.length(); + if (i1 > 0 && i1 < i3) + i3 = i1; + if (i2 > 0 && i2 < i3) + i3 = i2; + String k1 = k.substring(var.length() + 1, i3); + String var1 = k.substring(0, i3); + if (!mm.containsKey(k1)) { + Object str = createStructure(flatmap, var1); + if (str != null && (!(str instanceof String) || ((String) str).trim().length() > 0)) + mm.put(k1, str); + } + } + if (!mm.isEmpty()) + return mm; + + boolean arrayFound = false; + for (String k : flatmap.keySet()) + if (k.startsWith(var + "[")) { + arrayFound = true; + break; + } + + if (arrayFound) { + List<Object> ll = new ArrayList<>(); + + int length = Integer.MAX_VALUE; + String lengthStr = flatmap.get(var + "_length"); + if (lengthStr != null) { + try { + length = Integer.parseInt(lengthStr); + } catch (Exception e) { + log.warn("Invalid number for " + var + "_length:" + lengthStr); + } + } + + for (int i = 0; i < length; i++) { + Object v = createStructure(flatmap, var + '[' + i + ']'); + if (v == null) + break; + ll.add(v); + } + + if (!ll.isEmpty()) + return ll; + } + + return null; + } + + @SuppressWarnings("unchecked") + private static String generateXml(Object o, int indent, boolean escape) { + if (o == null) + return null; + + if (o instanceof String) + return escape ? escapeXml((String) o) : (String) o;; + + if (o instanceof Map) { + StringBuilder ss = new StringBuilder(); + Map<String, Object> mm = (Map<String, Object>) o; + for (String k : mm.keySet()) { + Object v = mm.get(k); + if (v instanceof String) { + String s = escape ? escapeXml((String) v) : (String) v; + ss.append(pad(indent)).append('<').append(k).append('>'); + ss.append(s); + ss.append("</").append(k).append('>').append('\n'); + } else if (v instanceof Map) { + ss.append(pad(indent)).append('<').append(k).append('>').append('\n'); + ss.append(generateXml(v, indent + 1, escape)); + ss.append(pad(indent)).append("</").append(k).append('>').append('\n'); + } else if (v instanceof List) { + List<Object> ll = (List<Object>) v; + for (Object o1 : ll) { + ss.append(pad(indent)).append('<').append(k).append('>').append('\n'); + ss.append(generateXml(o1, indent + 1, escape)); + ss.append(pad(indent)).append("</").append(k).append('>').append('\n'); + } + } + } + return ss.toString(); + } + + return null; + } + + private static String generateJson(Object o, boolean escape) { + if (o == null) + return null; + + StringBuilder ss = new StringBuilder(); + generateJson(ss, o, 0, false, escape); + return ss.toString(); + } + + @SuppressWarnings("unchecked") + private static void generateJson(StringBuilder ss, Object o, int indent, boolean padFirst, boolean escape) { + if (o instanceof String) { + String s = escape ? escapeJson((String) o) : (String) o; + if (padFirst) + ss.append(pad(indent)); + ss.append('"').append(s).append('"'); + return; + } + + if (o instanceof Map) { + Map<String, Object> mm = (Map<String, Object>) o; + + if (padFirst) + ss.append(pad(indent)); + ss.append("{\n"); + + boolean first = true; + for (String k : mm.keySet()) { + if (!first) + ss.append(",\n"); + first = false; + + Object v = mm.get(k); + ss.append(pad(indent + 1)).append('"').append(k).append("\": "); + generateJson(ss, v, indent + 1, false, escape); + } + + ss.append("\n"); + ss.append(pad(indent)).append('}'); + + return; + } + + if (o instanceof List) { + List<Object> ll = (List<Object>) o; + + if (padFirst) + ss.append(pad(indent)); + ss.append("[\n"); + + boolean first = true; + for (Object o1 : ll) { + if (!first) + ss.append(",\n"); + first = false; + + generateJson(ss, o1, indent + 1, true, escape); + } + + ss.append("\n"); + ss.append(pad(indent)).append(']'); + } + } + + public static String removeLastCommaJson(String s) { + StringBuilder sb = new StringBuilder(); + int k = 0; + int start = 0; + while (k < s.length()) { + int i11 = s.indexOf('}', k); + int i12 = s.indexOf(']', k); + int i1 = -1; + if (i11 < 0) + i1 = i12; + else if (i12 < 0) + i1 = i11; + else + i1 = i11 < i12 ? i11 : i12; + if (i1 < 0) + break; + + int i2 = s.lastIndexOf(',', i1); + if (i2 < 0) { + k = i1 + 1; + continue; + } + + String between = s.substring(i2 + 1, i1); + if (between.trim().length() > 0) { + k = i1 + 1; + continue; + } + + sb.append(s.substring(start, i2)); + start = i2 + 1; + k = i1 + 1; + } + + sb.append(s.substring(start, s.length())); + + return sb.toString(); + } + + public static String removeEmptyStructJson(String s) { + int k = 0; + while (k < s.length()) { + boolean curly = true; + int i11 = s.indexOf('{', k); + int i12 = s.indexOf('[', k); + int i1 = -1; + if (i11 < 0) { + i1 = i12; + curly = false; + } else if (i12 < 0) + i1 = i11; + else + if (i11 < i12) + i1 = i11; + else { + i1 = i12; + curly = false; + } + + if (i1 >= 0) { + int i2 = curly ? s.indexOf('}', i1) : s.indexOf(']', i1); + if (i2 > 0) { + String value = s.substring(i1 + 1, i2); + if (value.trim().length() == 0) { + int i4 = s.lastIndexOf('\n', i1); + if (i4 < 0) + i4 = 0; + int i5 = s.indexOf('\n', i2); + if (i5 < 0) + i5 = s.length(); + + s = s.substring(0, i4) + s.substring(i5); + k = 0; + } else + k = i1 + 1; + } else + break; + } else + break; + } + + return s; + } + + public static String removeEmptyStructXml(String s) { + int k = 0; + while (k < s.length()) { + int i1 = s.indexOf('<', k); + if (i1 < 0 || i1 == s.length() - 1) + break; + + char c1 = s.charAt(i1 + 1); + if (c1 == '?' || c1 == '!') { + k = i1 + 2; + continue; + } + + int i2 = s.indexOf('>', i1); + if (i2 < 0) { + k = i1 + 1; + continue; + } + + String closingTag = "</" + s.substring(i1 + 1, i2 + 1); + int i3 = s.indexOf(closingTag, i2 + 1); + if (i3 < 0) { + k = i2 + 1; + continue; + } + + String value = s.substring(i2 + 1, i3); + if (value.trim().length() > 0) { + k = i2 + 1; + continue; + } + + int i4 = s.lastIndexOf('\n', i1); + if (i4 < 0) + i4 = 0; + int i5 = s.indexOf('\n', i3); + if (i5 < 0) + i5 = s.length(); + + s = s.substring(0, i4) + s.substring(i5); + k = 0; + } + + return s; + } + + private static String escapeXml(String v) { + String s = v.replaceAll("&", "&"); + s = s.replaceAll("<", "<"); + s = s.replaceAll("'", "'"); + s = s.replaceAll("\"", """); + s = s.replaceAll(">", ">"); + return s; + } + + private static String escapeJson(String v) { + String s = v.replaceAll("\\\\", "\\\\\\\\"); + s = s.replaceAll("\"", "\\\\\""); + return s; + } + + private static String pad(int n) { + String s = ""; + for (int i = 0; i < n; i++) + s += '\t'; + return s; + } +} diff --git a/restapi-call-node/provider/src/main/java/org/openecomp/sdnc/restapicall/XmlParser.java b/restapi-call-node/provider/src/main/java/org/openecomp/sdnc/restapicall/XmlParser.java new file mode 100644 index 0000000..cf461e9 --- /dev/null +++ b/restapi-call-node/provider/src/main/java/org/openecomp/sdnc/restapicall/XmlParser.java @@ -0,0 +1,160 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdnc.restapicall; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +public class XmlParser { + + private static final Logger log = LoggerFactory.getLogger(XmlParser.class); + + public static Map<String, String> convertToProperties(String s, Set<String> listNameList) { + Handler handler = new Handler(listNameList); + try { + SAXParserFactory factory = SAXParserFactory.newInstance(); + SAXParser saxParser = factory.newSAXParser(); + InputStream in = new ByteArrayInputStream(s.getBytes()); + saxParser.parse(in, handler); + } catch (Exception e) { + e.printStackTrace(); + } + + return handler.getProperties(); + } + + private static class Handler extends DefaultHandler { + + private Set<String> listNameList; + + private Map<String, String> properties = new HashMap<>(); + + public Map<String, String> getProperties() { + return properties; + } + + public Handler(Set<String> listNameList) { + super(); + this.listNameList = listNameList; + if (this.listNameList == null) + this.listNameList = new HashSet<String>(); + } + + String currentName = ""; + String currentValue = ""; + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) + throws SAXException { + super.startElement(uri, localName, qName, attributes); + + String name = localName; + if (name == null || name.trim().length() == 0) + name = qName; + int i2 = name.indexOf(':'); + if (i2 >= 0) + name = name.substring(i2 + 1); + + if (currentName.length() > 0) + currentName += '.'; + currentName += name; + + String listName = removeIndexes(currentName); + + if (listNameList.contains(listName)) { + int len = getInt(properties, currentName + "_length"); + properties.put(currentName + "_length", String.valueOf(len + 1)); + currentName += "[" + len + "]"; + } + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + super.endElement(uri, localName, qName); + + String name = localName; + if (name == null || name.trim().length() == 0) + name = qName; + int i2 = name.indexOf(':'); + if (i2 >= 0) + name = name.substring(i2 + 1); + + if (currentValue.trim().length() > 0) { + currentValue = currentValue.trim(); + properties.put(currentName, currentValue); + + log.info("Added property: " + currentName + ": " + currentValue); + + currentValue = ""; + } + + int i1 = currentName.lastIndexOf("." + name); + if (i1 <= 0) + currentName = ""; + else + currentName = currentName.substring(0, i1); + } + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + super.characters(ch, start, length); + + String value = new String(ch, start, length); + currentValue += value; + } + + private static int getInt(Map<String, String> mm, String name) { + String s = mm.get(name); + if (s == null) + return 0; + return Integer.parseInt(s); + } + + private String removeIndexes(String currentName) { + String s = ""; + boolean add = true; + for (int i = 0; i < currentName.length(); i++) { + char c = currentName.charAt(i); + if (c == '[') + add = false; + else if (c == ']') + add = true; + else if (add) + s += c; + } + return s; + } + } +} diff --git a/restapi-call-node/provider/src/main/resources/META-INF/spring/restapi-call-node-context.xml b/restapi-call-node/provider/src/main/resources/META-INF/spring/restapi-call-node-context.xml new file mode 100644 index 0000000..7aa4fc5 --- /dev/null +++ b/restapi-call-node/provider/src/main/resources/META-INF/spring/restapi-call-node-context.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd"> + + <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> + <property name="locations" value="file:${SDNC_CONFIG_DIR}/ueb.properties" /> + <property name="ignoreResourceNotFound" value="true" /> + <property name="ignoreUnresolvablePlaceholders" value="true" /> + </bean> + + <!-- context:property-placeholder location="file:${SDNC_CONFIG_DIR}/ueb.properties" /--> + + <bean id="restapiCallNode" class="org.openecomp.sdnc.restapicall.RestapiCallNode"> + <property name="uebServers" value="${servers}" /> + </bean> + +</beans> diff --git a/restapi-call-node/provider/src/main/resources/META-INF/spring/restapi-call-node-osgi-context.xml b/restapi-call-node/provider/src/main/resources/META-INF/spring/restapi-call-node-osgi-context.xml new file mode 100644 index 0000000..aa12761 --- /dev/null +++ b/restapi-call-node/provider/src/main/resources/META-INF/spring/restapi-call-node-osgi-context.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<beans:beans xmlns="http://www.springframework.org/schema/osgi" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" + xsi:schemaLocation="http://www.springframework.org/schema/osgi + http://www.springframework.org/schema/osgi/spring-osgi.xsd + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd"> + + <service ref="restapiCallNode" interface="org.openecomp.sdnc.restapicall.RestapiCallNode" /> + +</beans:beans> diff --git a/restapi-call-node/provider/src/main/resources/default-ueb-message.json b/restapi-call-node/provider/src/main/resources/default-ueb-message.json new file mode 100644 index 0000000..4b1aa03 --- /dev/null +++ b/restapi-call-node/provider/src/main/resources/default-ueb-message.json @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +{ + "event":{ + "header":{ + "eventSource":"sdn-c" + }, + "body": + +${rootVarName} + + } +} diff --git a/restapi-call-node/provider/src/main/resources/get-multicast-data.json b/restapi-call-node/provider/src/main/resources/get-multicast-data.json new file mode 100644 index 0000000..f6155ee --- /dev/null +++ b/restapi-call-node/provider/src/main/resources/get-multicast-data.json @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +{ + "input": { + "sdnc-request-header": { + "svc-request-id": ${connection-details-notification-input.configuration-response-common.svc-request-id}, + "svc-action": "updatemulticastvpn" + }, + "service-information": { + "service-type": "AVPN", + "service-instance-id": ${tmp.ete-vpn-key} + } + } +} + diff --git a/restapi-call-node/provider/src/main/resources/northbound-api-template.json b/restapi-call-node/provider/src/main/resources/northbound-api-template.json new file mode 100644 index 0000000..d48c41c --- /dev/null +++ b/restapi-call-node/provider/src/main/resources/northbound-api-template.json @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +{ +"input": + { + "sdnc-request-header":{ + "svc-request-id": ${service-topology-operation-input.sdnc-request-header.svc-request-id}, + "svc-notification-url": ${service-topology-operation-input.sdnc-request-header.svc-notification-url} + }, + "request-information":{ + "request-id": ${service-topology-operation-input.request-information.request-id}, + "request-action": ${service-topology-operation-input.request-information.request-action}, + "request-sub-action": ${service-topology-operation-input.request-information.request-sub-action}, + "source": ${service-topology-operation-input.request-information.source}, + "notification-url": ${service-topology-operation-input.request-information.notification-url} + }, + "service-information":{ + "service-type": ${service-topology-operation-input.service-information.service-type}, + "service-instance-id": ${service-topology-operation-input.service-information.service-instance-id}, + "subscriber-name": ${service-topology-operation-input.service-information.subscriber-name}, + "subscriber-global-id": ${service-topology-operation-input.service-information.subscriber-global-id} + } +} + diff --git a/restapi-call-node/provider/src/main/resources/northbound-api-template.xml b/restapi-call-node/provider/src/main/resources/northbound-api-template.xml new file mode 100644 index 0000000..3738840 --- /dev/null +++ b/restapi-call-node/provider/src/main/resources/northbound-api-template.xml @@ -0,0 +1,41 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + <input xmlns="${northbound-xmlNS}"> + <request-information> + <notification-url>${service-topology-operation-input.request-information.notification-url}</notification-url> + <request-action>${service-topology-operation-input.request-information.request-action}</request-action> + <request-id>${service-topology-operation-input.request-information.request-id}</request-id> + <request-sub-action>${service-topology-operation-input.request-information.request-sub-action}</request-sub-action> + <source>${service-topology-operation-input.request-information.source}</source> + </request-information> + <sdnc-request-header> + <svc-notification-url>${service-topology-operation-input.sdnc-request-header.svc-notification-url}</svc-notification-url> + <svc-request-id>${service-topology-operation-input.sdnc-request-header.svc-request-id}</svc-request-id> + </sdnc-request-header> + <service-information> + <service-instance-id>${service-topology-operation-input.service-information.service-instance-id}</service-instance-id> + <service-type>${service-topology-operation-input.service-information.service-type}</service-type> + <subscriber-global-id>${service-topology-operation-input.service-information.subscriber-global-id}</subscriber-global-id> + <subscriber-name>${service-topology-operation-input.service-information.subscriber-name}</subscriber-name> + </service-information> + ${'northbound-anyData} + </input> diff --git a/restapi-call-node/provider/src/main/resources/service-configuration-notification-northbound-template.json b/restapi-call-node/provider/src/main/resources/service-configuration-notification-northbound-template.json new file mode 100644 index 0000000..347793f --- /dev/null +++ b/restapi-call-node/provider/src/main/resources/service-configuration-notification-northbound-template.json @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +{ + "input": { + "svc-request-id": ${service-configuration-notification-input.svc-request-id}, + "response-code": ${service-configuration-notification-input.response-code}, + "response-message": ${service-configuration-notification-input.response-message}, + "ack-final-indicator": ${service-configuration-notification-input.ack-final-indicator}, + "service-information": { + "service-type": "SERVICE1", + "service-instance-id": ${service-data.service-information.service-instance-id}, + "subscriber-name": ${service-data.service-information.subscriber-name}, + "subscriber-global-id": ${service-data.service-information.subscriber-global-id} + }, + "response-parameters": [ + ${repeat:service-configuration-notification-input.response-parameters_length: + { + "sequence-number": ${service-configuration-notification-input.response-parameters[${1}].sequence-number}, + "tag-name": ${service-configuration-notification-input.response-parameters[${1}].tag-name}, + "tag-value": ${service-configuration-notification-input.response-parameters[${1}].tag-value} + } + } + ] + } +} diff --git a/restapi-call-node/provider/src/main/resources/update-vpe-data-with-apply-group.json b/restapi-call-node/provider/src/main/resources/update-vpe-data-with-apply-group.json new file mode 100644 index 0000000..a82a6b4 --- /dev/null +++ b/restapi-call-node/provider/src/main/resources/update-vpe-data-with-apply-group.json @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +{ + "vrf-export-details": [ + ${repeat:restapi-result.ApplyGroupResponse.ApplyGroupResponseData[0].VrfDetails.VrfExport_length: + { + "vrf-export": ${restapi-result.ApplyGroupResponse.ApplyGroupResponseData[0].VrfDetails.VrfExport[${1}]} + } + } + ], + "vrf-import-details": [ + ${repeat:restapi-result.ApplyGroupResponse.ApplyGroupResponseData[0].VrfDetails.VrfImport_length: + { + "vrf-import": ${restapi-result.ApplyGroupResponse.ApplyGroupResponseData[0].VrfDetails.VrfImport[${1}]} + } + } + ], + "apply-group-template": [ + ${repeat:restapi-result.ApplyGroupResponse.ApplyGroupResponseData[0].VrfDetails.ApplyGroup_length: + { + "apply-group": ${restapi-result.ApplyGroupResponse.ApplyGroupResponseData[0].VrfDetails.ApplyGroup[${1}].ApplyGroup} + } + } + ], + "community-list": [ + ${repeat:restapi-result.ApplyGroupResponse.ApplyGroupResponseData[0].VrfDetails.CommunityList_length: + { + "member": ${restapi-result.ApplyGroupResponse.ApplyGroupResponseData[0].VrfDetails.CommunityList[${1}].member}, + "name": ${restapi-result.ApplyGroupResponse.ApplyGroupResponseData[0].VrfDetails.CommunityList[${1}].name} + } + } + ] +} + diff --git a/restapi-call-node/provider/src/main/resources/vnf-information-update.json b/restapi-call-node/provider/src/main/resources/vnf-information-update.json new file mode 100644 index 0000000..425f0f3 --- /dev/null +++ b/restapi-call-node/provider/src/main/resources/vnf-information-update.json @@ -0,0 +1,24 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +{ +"generic-vnf-service" :${vnf-service.generic-vnf-service} +} diff --git a/restapi-call-node/provider/src/main/resources/vpn-allocation-request.json b/restapi-call-node/provider/src/main/resources/vpn-allocation-request.json new file mode 100644 index 0000000..6c84274 --- /dev/null +++ b/restapi-call-node/provider/src/main/resources/vpn-allocation-request.json @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +{ + "AllocateVpnResourcesRequest": { + "message-id": "${service-data.oper-status.modify-timestamp}", + "service-instance-id": "${service-data.service-information.service-instance-id}", + "vrf-request-type": { + "vpn-id": "${service-data.avpn-logicalchannel-information.vpn-id}", + "vpn-service": "${service-data.service-information.service-type}", + "e2e-vpn-id": "${service-data.avpn-logicalchannel-information.e2e-vpn-id}", + "vpe-name": "${service-data.avpn-logicalchannel-information.evc-endpoint-information.vpe-name}", + "asn": "${service-data.avpn-logicalchannel-information.carrier-asn}", + "route-group-name": "${service-data.avpn-logicalchannel-information.bgp-options.neighbor-address-information.route-group-name}", + "hub-or-spoke": "${service-data.avpn-logicalchannel-information.hub-or-spoke}" + } + } +} diff --git a/restapi-call-node/provider/src/main/resources/vpn-information-update.json b/restapi-call-node/provider/src/main/resources/vpn-information-update.json new file mode 100644 index 0000000..7977066 --- /dev/null +++ b/restapi-call-node/provider/src/main/resources/vpn-information-update.json @@ -0,0 +1,24 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +{ +"vpn-information" :${vpe-vpn-service.vpn-information} +} diff --git a/restapi-call-node/provider/src/main/resources/vrf-service-configuration-information-template.json b/restapi-call-node/provider/src/main/resources/vrf-service-configuration-information-template.json new file mode 100644 index 0000000..f7e8432 --- /dev/null +++ b/restapi-call-node/provider/src/main/resources/vrf-service-configuration-information-template.json @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +{ + "input": { + + "e2e-vpn-key": ${service-data.avpn-logicalchannel-information.e2e-vpn-id}, + "logical-channel-id": ${service-data.service-information.service-instance-id}, + "vpe-name": ${service-data.avpn-logicalchannel-information.evc-endpoint-information.vpe-name}, + "rpc-action": ${tmp.rpc-action}, + + "vpn-information": ${vpe-vpn-service.vpn-information}, + "vrf-details": ${vpe-vpn-service.vpn-information.vrf-details}, + "vrf-vlan-resources": { + "logical-channel-id": ${service-data.service-information.service-instance-id}, + "logical-channel-status": ${tmp.logical-channel-status} + } + } +} diff --git a/restapi-call-node/provider/src/main/resources/vrf-update-vlan-status-template.json b/restapi-call-node/provider/src/main/resources/vrf-update-vlan-status-template.json new file mode 100644 index 0000000..7a6cab3 --- /dev/null +++ b/restapi-call-node/provider/src/main/resources/vrf-update-vlan-status-template.json @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +{ + "input": { + "e2e-vpn-key": ${service-data.avpn-logicalchannel-information.e2e-vpn-id}, + "logical-channel-id": ${service-data.service-information.service-instance-id}, + "vpe-name": ${service-data.avpn-logicalchannel-information.evc-endpoint-information.vpe-name}, + "rpc-action": ${tmp.rpc-action}, + "vrf-vlan-resources": { + "logical-channel-id": ${service-data.service-information.service-instance-id}, + "logical-channel-status": ${tmp.logical-channel-status} + } + } +} diff --git a/restapi-call-node/provider/src/main/resources/vrf-update.json b/restapi-call-node/provider/src/main/resources/vrf-update.json new file mode 100644 index 0000000..778e4b2 --- /dev/null +++ b/restapi-call-node/provider/src/main/resources/vrf-update.json @@ -0,0 +1,77 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +{ + "vpn-vame": ${allocate-vpn-resource-notification-input.vpn-data[0].vpn-name}, + "vpn-id": ${allocate-vpn-resource-notification-input.vpn-data[0].vpn-id}, + "vrf-details": [ + ${repeat:allocate-vpn-resource-notification-input.vpn-data[0].vrf-information_length: + { + "vrf-export-details": [ + ${repeat:allocate-vpn-resource-notification-input.vpn-data[0].vrf-information[${1}].vrf-export-details_length: + { + "vrf-export": ${allocate-vpn-resource-notification-input.vpn-data[0].vrf-information[${1}].vrf-export-details[${2}].vrf-export} + } + } + ], + "vrf-name": ${allocate-vpn-resource-notification-input.vpn-data[0].vrf-information[${1}].vrf-name}, + "vpe-name": ${allocate-vpn-resource-notification-input.vpn-data[0].vrf-information[${1}].vpe-name}, + "vrf-import-details": [ + ${repeat:allocate-vpn-resource-notification-input.vpn-data[0].vrf-information[${1}].vrf-import-details_length: + { + "vrf-import": ${allocate-vpn-resource-notification-input.vpn-data[0].vrf-information[${1}].vrf-import-details[${2}].vrf-import} + } + } + ], + "apply-group-template": [ + ${repeat:allocate-vpn-resource-notification-input.vpn-data[0].vrf-information[${1}].apply-group-template_length: + { + "apply-group": ${allocate-vpn-resource-notification-input.vpn-data[0].vrf-information[${1}].apply-group-template[${2}].apply-group} + } + } + ], + "community-list": [ + ${repeat:allocate-vpn-resource-notification-input.vpn-data[0].vrf-information[${1}].community-list_length: + { + "member": ${allocate-vpn-resource-notification-input.vpn-data[0].vrf-information[${1}].community-list[${2}].name}, + "name": ${allocate-vpn-resource-notification-input.vpn-data[0].vrf-information[${1}].community-list[${2}].member} + } + } + ], + "router-distinguisher": ${allocate-vpn-resource-notification-input.vpn-data[0].vrf-information[${1}].router-distinguisher} + } + } + ], + "spoke-routes": { + "route-target": ${allocate-vpn-resource-notification-input.vpn-data[0].spoke-route-target.route-target} + }, + + "route-target-details": [ + ${repeat:allocate-vpn-resource-notification-input.vpn-data[0].route-target-details_length: + { + "route-target": ${allocate-vpn-resource-notification-input.vpn-data[0].route-target-details[${1}].route-target}, + "route-target-type": ${allocate-vpn-resource-notification-input.vpn-data[0].route-target-details[${1}].route-target-type} + } + } + ], + + "e2e-vpn-key": ${allocate-vpn-resource-notification-input.vpn-data[0].e2e-vpn-id} +} |