summaryrefslogtreecommitdiffstats
path: root/appc-dg/appc-dg-shared/appc-dg-mdsal-store
diff options
context:
space:
mode:
Diffstat (limited to 'appc-dg/appc-dg-shared/appc-dg-mdsal-store')
-rw-r--r--appc-dg/appc-dg-shared/appc-dg-mdsal-store/pom.xml45
-rw-r--r--appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/MDSALStore.java62
-rw-r--r--appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/exception/MDSALStoreException.java69
-rw-r--r--appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/impl/Constants.java108
-rw-r--r--appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/impl/MDSALStoreFactory.java47
-rw-r--r--appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/impl/MDSALStoreImpl.java137
-rw-r--r--appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/objects/BundleInfo.java71
-rw-r--r--appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/operation/ConfigOperation.java289
-rw-r--r--appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/operation/ConfigOperationRequestFormatter.java51
9 files changed, 879 insertions, 0 deletions
diff --git a/appc-dg/appc-dg-shared/appc-dg-mdsal-store/pom.xml b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/pom.xml
new file mode 100644
index 000000000..8123d17bb
--- /dev/null
+++ b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/pom.xml
@@ -0,0 +1,45 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-dg-shared</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>appc-dg-mdsal-store</artifactId>
+ <packaging>jar</packaging>
+
+ <name>appc-dg-mdsal-store</name>
+ <url>http://maven.apache.org</url>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-model-api</artifactId>
+ <version>${odl.yangtools.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/MDSALStore.java b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/MDSALStore.java
new file mode 100644
index 000000000..cb6e2fd11
--- /dev/null
+++ b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/MDSALStore.java
@@ -0,0 +1,62 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-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.appc.mdsal;
+
+import org.openecomp.appc.mdsal.exception.MDSALStoreException;
+import org.openecomp.appc.mdsal.objects.BundleInfo;
+
+import java.util.Date;
+
+/**
+ * Provides APIs for interacting with MD-SAL store
+ */
+public interface MDSALStore {
+
+ /**
+ * Checks the presence of any yang module in the MD-SAL store,
+ * <i>Due to limitation of SchemaContext interface of ODL that it does not
+ * contain the information about dynamically loaded yang modules, it
+ * checks the presence of OSGI bundle</i>
+ * @param moduleName Name of the Module
+ * @param revision revision of the Module
+ * @return returns true- module is present, false - module is absent
+ */
+ boolean isModulePresent(String moduleName, Date revision);
+
+ /**
+ * This method will be used to store yang module to MD-SAL store
+ * @param yang - yang module that need to be stored. In String format
+ * @param bundleInfo - Bundle Information that contains name , description, version , location. These parameters used to create bundle which will push yang to MD-SAL store.
+ * @throws MDSALStoreException
+ */
+ void storeYangModule(String yang, BundleInfo bundleInfo) throws MDSALStoreException;
+
+ /**
+ * This method is used to store configuration JSON to MD-SAL store. It invokes store configuration Operation with required parameters
+ * @param moduleName - Yang module name where JSON need to be posted
+ * @param requestId - Request ID which is used as unique key for configuration JSON
+ * @param configJSON - String value of configuration JSON that needs to be stored in MD-SAl store
+ * @throws MDSALStoreException
+ */
+ void storeJson(String moduleName , String requestId , String configJSON ) throws MDSALStoreException;
+
+}
diff --git a/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/exception/MDSALStoreException.java b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/exception/MDSALStoreException.java
new file mode 100644
index 000000000..0628ef78d
--- /dev/null
+++ b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/exception/MDSALStoreException.java
@@ -0,0 +1,69 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-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.appc.mdsal.exception;
+
+/**
+ * This is custom exception type defined for MD-SAL store. All exceptions thrown by mdsal store module need to be wrapped in this class.
+*/
+ public class MDSALStoreException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public MDSALStoreException(){
+ }
+
+ /**
+ * Create MDSALStoreException using only message.
+ * @param message -- message to the caller.
+ */
+ public MDSALStoreException (String message){
+ super(message);
+ }
+
+ /**
+ * Create MDSALStoreException using orignal cause
+ * @param cause - cause that is being wrapped / suppressed.
+ */
+ public MDSALStoreException (Throwable cause){
+ super(cause);
+ }
+
+ /**
+ *
+ * @param message - message to the caller.
+ * @param cause - cause that is being wrapped / suppressed .
+ */
+ public MDSALStoreException(String message , Throwable cause){
+ super(message , cause);
+ }
+
+ /**
+ *
+ * @param message - message to the caller.
+ * @param cause - cause that is being wrapped / suppressed .
+ * @param enableSuppression - Indicates if suppression is enabled.
+ * @param writableStackTrace - Indicates if writable stacktrace is supported
+ */
+ public MDSALStoreException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
diff --git a/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/impl/Constants.java b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/impl/Constants.java
new file mode 100644
index 000000000..a41c49de7
--- /dev/null
+++ b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/impl/Constants.java
@@ -0,0 +1,108 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-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.appc.mdsal.impl;
+/**
+ * This class contains the definitions of all constant values used in the appc-dg-mdsal-store
+ * These properties are used for creating osgi bundle zip file. It also defines contents for Blueprint.xml file of bundle
+*/
+public class Constants {
+
+ private Constants(){}
+ /**
+ * Manifest attribute for OSGI Bundle Name
+ */
+ public static final String MANIFEST_ATTR_BUNDLE_NAME= "Bundle-Name";
+
+ /**
+ * Manifest attribute for OSGI Bundle Symbolic Name
+ */
+ public static final String MANIFEST_ATTR_BUNDLE_SYMBOLIC_NAME= "Bundle-SymbolicName";
+
+ /**
+ * Manifest attribute for OSGI Bundle Description
+ */
+ public static final String MANIFEST_ATTR_BUNDLE_DESCRIPTION= "Bundle-Description";
+
+ /**
+ * Manifest attribute for OSGI Bundle Manifest version
+ */
+ public static final String MANIFEST_ATTR_BUNDLE_MANIFEST_VERSION= "Bundle-ManifestVersion";
+
+ /**
+ * Manifest attribute for OSGI Bundle Version
+ */
+ public static final String MANIFEST_ATTR_BUNDLE_VERSION= "Bundle-Version";
+
+ /**
+ * Manifest attribute for OSGI Bundle Blueprint
+ */
+ public static final String MANIFEST_ATTR_BUNDLE_BLUEPRINT= "Bundle-Blueprint";
+
+ /**
+ * Manifest value for Mainfest Version
+ */
+ public static final String MANIFEST_VALUE_VERSION= "1.0";
+
+ /**
+ * Manifest value for OSGI Bundle Vesion
+ */
+ public static final String MANIFEST_VALUE_BUNDLE_MAN_VERSION= "2";
+
+ /**
+ * Manifest value for OSGI Bundle Blueprint location
+ */
+ public static final String MANIFEST_VALUE_BUNDLE_BLUEPRINT= "OSGI-INF/blueprint/blueprint.xml";
+
+ /**
+ * Base URL for config actions exposed by RESTCONF API
+ */
+
+ public static final String CONFIG_URL = "https://localhost:8443/restconf/config";
+
+ /**
+ * Content for blueprint.xml used while creation of OSGI bundle.
+ */
+ public static final String BLUEPRINT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+ "<!--\n" +
+ " Starter Blueprint Camel Definition appc-aai-adapter-blueprint\n" +
+ "-->\n" +
+ "<blueprint xmlns=\"http://www.osgi.org/xmlns/blueprint/v1.0.0\"\n" +
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+ " xsi:schemaLocation=\"http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd\">\n" +
+ "\n" +
+ "</blueprint>";
+
+ /**
+ * HTTP Header attribute for Content type - JSON
+ */
+ public static final String OPERATION_APPLICATION_JSON= " application/json";
+
+ /**
+ * HTTP protocol used for config operations
+ */
+ public static final String OPERATION_HTTPS= "https";
+
+ /**
+ * Constant for backslash to be used while formatting URL
+ */
+ public static final String URL_BACKSLASH ="/";
+}
diff --git a/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/impl/MDSALStoreFactory.java b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/impl/MDSALStoreFactory.java
new file mode 100644
index 000000000..7550ad9e2
--- /dev/null
+++ b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/impl/MDSALStoreFactory.java
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-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.appc.mdsal.impl;
+
+import org.openecomp.appc.mdsal.MDSALStore;
+
+/*
+ * Factory class to create/get instance of MDSALStore
+ */
+public class MDSALStoreFactory {
+ private static class ReferenceHolder{
+ private static MDSALStore store = new MDSALStoreImpl();
+ private ReferenceHolder(){}
+ }
+ private MDSALStoreFactory(){
+
+ }
+
+ /**
+ * Method for creating MDSALStore instance, It creates an instance of
+ * MDSALStoreImpl once and returns the same instance everytime it is invoked.
+ * @return
+ */
+ public static MDSALStore createMDSALStore (){
+ return ReferenceHolder.store;
+ }
+}
+
diff --git a/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/impl/MDSALStoreImpl.java b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/impl/MDSALStoreImpl.java
new file mode 100644
index 000000000..6f43bfc65
--- /dev/null
+++ b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/impl/MDSALStoreImpl.java
@@ -0,0 +1,137 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-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.appc.mdsal.impl;
+
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.mdsal.MDSALStore;
+import org.openecomp.appc.mdsal.exception.MDSALStoreException;
+import org.openecomp.appc.mdsal.objects.BundleInfo;
+import org.openecomp.appc.mdsal.operation.ConfigOperation;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.Date;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+/**
+ * Implementation of MDSALStore
+ */
+public class MDSALStoreImpl implements MDSALStore{
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(MDSALStoreImpl.class);
+
+ MDSALStoreImpl(){
+ ConfigOperation.setUrl(Constants.CONFIG_URL);
+ ConfigOperation.setAuthentication(null,null);
+ }
+
+
+ @Override
+ public boolean isModulePresent(String moduleName, Date revision) {
+
+ if(logger.isDebugEnabled()){
+ logger.debug("isModulePresent invoked with moduleName = " +moduleName + " , revision = " +revision);
+ }
+
+ BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
+ /**
+ * SchemaContext interface of ODL provides APIs for querying details of yang modules
+ * loaded into MD-SAL store, but its limitation is, it only returns information about
+ * static yang modules loaded on server start up, it does not return information about
+ * the yang modules loaded dynamically. Due to this limitation, we are checking the
+ * presence of OSGI bundle instead of yang module. (Note: Assuming OSGI bundle is named
+ * with the yang module name).
+ */
+
+ Bundle bundle = bundleContext.getBundle(moduleName);
+ if(logger.isDebugEnabled()){
+ logger.debug("isModulePresent returned = " + (bundle != null));
+ }
+ return bundle != null;
+ }
+
+ @Override
+ public void storeYangModule(String yang, BundleInfo bundleInfo) throws MDSALStoreException {
+
+ BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
+ byte[] byteArray = createBundleJar(yang, Constants.BLUEPRINT, bundleInfo);
+
+ try (ByteArrayInputStream inputStream = new ByteArrayInputStream(byteArray)){
+ Bundle bundle = bundleContext.installBundle(bundleInfo.getLocation(), inputStream);
+ bundle.start();
+ } catch (Exception e) {
+ logger.error("Error storing yang module: " + yang + ". Error message: " + e.getMessage());
+ throw new MDSALStoreException("Error storing yang module: " + yang + " " + e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public void storeJson( String module , String requestId ,String configJSON) throws MDSALStoreException {
+
+ try {
+ ConfigOperation.storeConfig(configJSON , module , org.openecomp.appc.Constants.YANG_BASE_CONTAINER, org.openecomp.appc.Constants.YANG_VNF_CONFIG_LIST,requestId,org.openecomp.appc.Constants.YANG_VNF_CONFIG);
+ } catch (APPCException e) {
+ throw new MDSALStoreException("Exception while storing config json to MDSAL store." +e.getMessage(), e);
+ }
+ }
+
+ private byte[] createBundleJar(String yang, String blueprint, BundleInfo bundleInfo) throws MDSALStoreException {
+
+ Manifest manifest = new Manifest();
+ manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, Constants.MANIFEST_VALUE_VERSION);
+ manifest.getMainAttributes().put(new Attributes.Name(Constants.MANIFEST_ATTR_BUNDLE_NAME), bundleInfo.getName());
+ manifest.getMainAttributes().put(new Attributes.Name(Constants.MANIFEST_ATTR_BUNDLE_SYMBOLIC_NAME), bundleInfo.getName());
+ manifest.getMainAttributes().put(new Attributes.Name(Constants.MANIFEST_ATTR_BUNDLE_DESCRIPTION), bundleInfo.getDescription());
+ manifest.getMainAttributes().put(new Attributes.Name(Constants.MANIFEST_ATTR_BUNDLE_MANIFEST_VERSION), Constants.MANIFEST_VALUE_BUNDLE_MAN_VERSION);
+ manifest.getMainAttributes().put(new Attributes.Name(Constants.MANIFEST_ATTR_BUNDLE_VERSION), String.valueOf(bundleInfo.getVersion()));
+ manifest.getMainAttributes().put(new Attributes.Name(Constants.MANIFEST_ATTR_BUNDLE_BLUEPRINT), Constants.MANIFEST_VALUE_BUNDLE_BLUEPRINT);
+
+ byte[] retunValue;
+
+ try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ JarOutputStream jarOutputStream = new JarOutputStream(outputStream, manifest)) {
+ jarOutputStream.putNextEntry(new JarEntry("META-INF/yang/"));
+ jarOutputStream.putNextEntry(new JarEntry("META-INF/yang/"+bundleInfo.getName()+".yang"));
+ jarOutputStream.write(yang.getBytes());
+ jarOutputStream.closeEntry();
+
+ jarOutputStream.putNextEntry(new JarEntry("OSGI-INF/blueprint/"));
+ jarOutputStream.putNextEntry(new JarEntry(Constants.MANIFEST_VALUE_BUNDLE_BLUEPRINT));
+ jarOutputStream.write(blueprint.getBytes());
+ jarOutputStream.closeEntry();
+ jarOutputStream.close();
+ retunValue = outputStream.toByteArray();
+ } catch (Exception e) {
+ logger.error("Error creating bundle jar: " + bundleInfo.getName() + ". Error message: " + e.getMessage());
+ throw new MDSALStoreException("Error creating bundle jar: " + bundleInfo.getName() + " " + e.getMessage(), e);
+ }
+ return retunValue;
+ }
+}
diff --git a/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/objects/BundleInfo.java b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/objects/BundleInfo.java
new file mode 100644
index 000000000..f4bd1feba
--- /dev/null
+++ b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/objects/BundleInfo.java
@@ -0,0 +1,71 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-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.appc.mdsal.objects;
+/**
+ * Holds bundle information which includes name , description , version and location. This information will be used to create osgi bundle.
+ */
+ public class BundleInfo {
+
+ private String name;
+ private String description;
+ private Integer version;
+ private String location;
+
+ /**
+ * Creates an object of BundleInfo with version initialized to 1
+ */
+ public BundleInfo(){
+ version =1;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Integer getVersion() {
+ return version;
+ }
+
+ public void setVersion(Integer version) {
+ this.version = version;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public void setLocation(String location) {
+ this.location = location;
+ }
+}
diff --git a/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/operation/ConfigOperation.java b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/operation/ConfigOperation.java
new file mode 100644
index 000000000..15b632731
--- /dev/null
+++ b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/operation/ConfigOperation.java
@@ -0,0 +1,289 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-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.appc.mdsal.operation;
+
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.mdsal.impl.Constants;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.http.HttpHeaders;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpVersion;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.scheme.PlainSocketFactory;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.params.HttpProtocolParams;
+import org.apache.http.protocol.HTTP;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.Socket;
+import java.net.URL;
+import java.security.*;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.apache.commons.io.IOUtils;
+
+/**
+ * Provides method to store configuration to MD-SAL store. It also exposes doPut operation which can be used to invoke REST Put operation.
+*/
+public class ConfigOperation {
+ private static final EELFLogger LOG = EELFManager.getInstance().getLogger(ConfigOperation.class);
+
+ private static URL url;
+ private static String basicAuth;
+
+ ConfigOperation(){}
+
+ private static ConfigOperationRequestFormatter requestFormatter = new ConfigOperationRequestFormatter();
+
+ private static ObjectMapper mapper = new ObjectMapper();
+
+ /**
+ * This method stores configuration JSON to MD-SAL store. Following input parameters are expected as input
+ * @param configJson - configuration JSON as String. This value will be stored in MD-SAL store
+ * @param module - Module name that contains yang Schema
+ * @param containerName - yang container name which will be used as base container.
+ * @param subModules - Sub modules list if any. Order of sub module is top to bottom.
+ * @throws APPCException
+ */
+ public static void storeConfig(String configJson , String module, String containerName, String... subModules ) throws APPCException {
+ if (configJson == null) {
+ throw new APPCException("Provided message was null");
+ }
+ LOG.debug("Config JSON: " + configJson +"\n"
+ +"module" + module +"\n"
+ +"containerName" + containerName +"\n"
+ +"subModules length : " + subModules.length );
+
+ int httpCode;
+ String respBody ;
+ try {
+ String path = requestFormatter.buildPath(url, module, containerName, subModules);
+ LOG.debug("Configuration Path : " + path);
+ URL serviceUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), path);
+ HttpResponse response = doPut(serviceUrl , configJson);
+ httpCode = response.getStatusLine().getStatusCode();
+ respBody = IOUtils.toString(response.getEntity().getContent());
+ } catch (IOException e) {
+ LOG.error("Error while storing configuration json "+e.getMessage(), e);
+ throw new APPCException(e);
+ }
+
+ if (httpCode != 200 ) {
+ try {
+ ArrayList<String> errorMessage = new ArrayList<>();
+ JsonNode responseJson = toJsonNodeFromJsonString(respBody);
+ if(responseJson!=null && responseJson.get("errors")!=null) {
+ JsonNode errors = responseJson.get("errors").get("error");
+ for (Iterator<JsonNode> i = errors.elements();i.hasNext();){
+ JsonNode error = i.next();
+ errorMessage.add(error.get("error-message").textValue());
+ }
+ }
+ throw new APPCException("Failed to load config JSON to MD SAL store. Error Message:" + errorMessage.toString());
+ } catch (Exception e) {
+ LOG.error("Error while loading config JSON to MD SAL store. "+e.getMessage(), e);
+ throw new APPCException("Error while loading config JSON to MD SAL store. "+ e.getMessage(),e);
+ }
+ }
+ }
+
+ /**
+ * This is Generic method that can be used to perform REST Put operation
+ * @param url - Destination URL for put
+ * @param body - payload for put action which will be sent as request body.
+ * @return - HttpResponse object which is returned from put REST call.
+ * @throws APPCException
+ */
+ public static HttpResponse doPut (URL url, String body) throws APPCException {
+ HttpPut put;
+ try {
+ put = new HttpPut(url.toExternalForm());
+ put.setHeader(HttpHeaders.CONTENT_TYPE, Constants.OPERATION_APPLICATION_JSON);
+ put.setHeader(HttpHeaders.ACCEPT, Constants.OPERATION_APPLICATION_JSON);
+
+ if (basicAuth != null) {
+ put.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + basicAuth);
+ }
+
+ StringEntity entity = new StringEntity(body);
+ entity.setContentType(Constants.OPERATION_APPLICATION_JSON);
+ put.setEntity(new StringEntity(body));
+ } catch (UnsupportedEncodingException e) {
+ throw new APPCException(e);
+ }
+
+ HttpClient client = getHttpClient();
+
+ try {
+ return client.execute(put);
+ } catch (IOException e) {
+ throw new APPCException(e);
+ }
+
+ }
+
+ /**
+ * Updates the static var URL and returns the value;
+ *
+ * @return The new value of URL
+ */
+ public static String getUrl() {
+ return url.toExternalForm();
+ }
+
+ public static void setUrl(String newUrl) {
+ try {
+ url = new URL(newUrl);
+ } catch (MalformedURLException e) {
+ LOG.error("Malformed URL " +newUrl + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Sets the basic authentication header for the given user and password. If either entry is null then set basic auth
+ * to null
+ *
+ * @param user The user with optional domain name (for AAF)
+ * @param password The password for the user
+ * @return The new value of the basic auth string that will be used in the request headers
+ */
+ public static String setAuthentication(String user, String password) {
+ if (user != null && password != null) {
+ String authStr = user + ":" + password;
+ basicAuth = new String(Base64.encodeBase64(authStr.getBytes()));
+ } else {
+ basicAuth = null;
+ }
+ return basicAuth;
+ }
+
+ @SuppressWarnings("deprecation")
+ private static HttpClient getHttpClient() throws APPCException {
+ HttpClient client;
+ if (url.getProtocol().equals(Constants.OPERATION_HTTPS)) {
+ try {
+ KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ trustStore.load(null, null);
+ MySSLSocketFactory sf = new MySSLSocketFactory(trustStore);
+ sf.setHostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+
+ HttpParams params = new BasicHttpParams();
+ HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
+ HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
+
+ SchemeRegistry registry = new SchemeRegistry();
+ registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
+ registry.register(new Scheme(Constants.OPERATION_HTTPS, sf, 443));
+ registry.register(new Scheme(Constants.OPERATION_HTTPS, sf, 8443));
+ registry.register(new Scheme("http", sf, 8181));
+
+ ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
+ client = new DefaultHttpClient(ccm, params);
+ } catch (Exception e) {
+ LOG.error("Error creating HTTP Client. Creating default client." , e);
+ client = new DefaultHttpClient();
+ }
+ } else if ("http".equals(url.getProtocol())) {
+ client = new DefaultHttpClient();
+ } else {
+ throw new APPCException(
+ "The provider.topology.url property is invalid. The url did not start with http[s]");
+ }
+ return client;
+ }
+
+ @SuppressWarnings("deprecation")
+ private static class MySSLSocketFactory extends SSLSocketFactory {
+ private SSLContext sslContext = SSLContext.getInstance("TLS");
+
+ private MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException,
+ KeyStoreException, UnrecoverableKeyException {
+ super(truststore);
+
+ TrustManager tm = new X509TrustManager() {
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+ LOG.debug("Inside checkClientTrusted");
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+ LOG.debug("Inside checkServerTrusted");
+ }
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ return new X509Certificate[1];
+ }
+ };
+
+ sslContext.init(null, new TrustManager[]{
+ tm
+ }, null);
+ }
+
+ @Override
+ public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
+ throws IOException {
+ return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
+ }
+
+ @Override
+ public Socket createSocket() throws IOException {
+ return sslContext.getSocketFactory().createSocket();
+ }
+ }
+
+ private static JsonNode toJsonNodeFromJsonString(String jsonStr) {
+ JsonNode jsonNode = null;
+ if(jsonStr != null) {
+ try {
+ jsonNode = mapper.readTree(jsonStr);
+ } catch (IOException e) {
+ LOG.warn(String.format("Could not map %s to jsonNode.", jsonStr), e);
+ }
+ }
+ return jsonNode;
+ }
+
+}
diff --git a/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/operation/ConfigOperationRequestFormatter.java b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/operation/ConfigOperationRequestFormatter.java
new file mode 100644
index 000000000..13a587477
--- /dev/null
+++ b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/operation/ConfigOperationRequestFormatter.java
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-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.appc.mdsal.operation;
+
+import org.openecomp.appc.mdsal.impl.Constants;
+
+import java.net.URL;
+/**
+ * Creates request url path for config actions based on parameter like module name , container-name and sub modules if any.
+ */
+
+public class ConfigOperationRequestFormatter {
+ /**
+ * Build a request url path for config actions
+ * @param url - base url
+ * @param module - yang module name
+ * @param containerName - yang container name
+ * @param subModules - sub module /container names as string in varargs ( String ) format
+ * @return - resultant path in String format
+ */
+ public String buildPath(URL url,String module, String containerName , String... subModules ) {
+
+ StringBuilder path = new StringBuilder( url.getPath()+ Constants.URL_BACKSLASH + module + ":"+containerName + Constants.URL_BACKSLASH);
+ if(subModules.length >0){
+ for(String subModule : subModules){
+ path.append(subModule);
+ path.append("/");
+ }
+ }
+ return path.toString();
+ }
+}