ml.distribution.POLLING_TIMEOUT=20
ml.distribution.USER=<DIST_USER>
ml.distribution.ARTIFACT_TYPES=MODEL_QUERY_SPEC,TOSCA_CSAR
-
-# Model Loader Client Configuration for the A&AI REST interface
-ml.aai.BASE_URL=https://<AAI_HOST>:8443
-ml.aai.MODEL_URL=/aai/v*/service-design-and-creation/models/model/
-ml.aai.NAMED_QUERY_URL=/aai/v*/service-design-and-creation/named-queries/named-query/
-ml.aai.VNF_IMAGE_URL=/aai/v*/service-design-and-creation/vnf-images
-ml.aai.KEYSTORE_FILE=<AAI_KEYSTORE>
-ml.aai.KEYSTORE_PASSWORD=<OBF:1234>
-ml.aai.AUTH_USER=ModelLoader
-ml.aai.AUTH_PASSWORD=
-
-# Model Loader Client Configuration for the Babel Service
-ml.babel.BASE_URL=https://<BABEL_HOST>:9516
-ml.babel.GENERATE_ARTIFACTS_URL=/services/babel-service/v1/app/generateArtifacts
-ml.babel.KEYSTORE_FILE=<BABEL_KEYSTORE>
-ml.babel.KEYSTORE_PASSWORD=<OBF:1234>
-ml.babel.TRUSTSTORE_FILE=<BABEL_TRUSTSTORE>
-ml.babel.TRUSTSTORE_PASSWORD=<OBF:1234>
<groupId>org.onap.aai.model-loader</groupId>
<artifactId>model-loader</artifactId>
<name>aai-model-loader</name>
- <version>1.14.2-SNAPSHOT</version>
+ <version>1.14.3-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-configuration-processor</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
*/
package org.onap.aai.modelloader;
+import org.onap.aai.modelloader.config.BabelProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
/**
* Model Loader Spring Boot Application.
*/
@SpringBootApplication
+@EnableConfigurationProperties(BabelProperties.class)
public class ModelLoaderApplication {
public static void main(String[] args) {
--- /dev/null
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2025 Deutsche Telekom AG 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.onap.aai.modelloader.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+@Component
+@ConfigurationProperties(prefix = "ml.aai")
+public class AaiProperties {
+ private String baseUrl;
+ private String modelUrl;
+ private String namedQueryUrl;
+ private String vnfImageUrl;
+ private String authUser;
+ private String authPassword;
+ private boolean useGizmo;
+}
--- /dev/null
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2025 Deutsche Telekom AG 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.onap.aai.modelloader.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+@Component
+@ConfigurationProperties(prefix = "ml.babel")
+public class BabelProperties {
+ private String baseUrl;
+ private String generateArtifactsUrl;
+}
package org.onap.aai.modelloader.config;
-import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import java.util.Optional;
import java.util.Properties;
import org.apache.commons.lang3.StringUtils;
// Configuration file structure
public static final String PREFIX_MODEL_LOADER_CONFIG = "ml";
public static final String PREFIX_DISTRIBUTION_CLIENT = PREFIX_MODEL_LOADER_CONFIG + ".distribution.";
- public static final String PREFIX_AAI = PREFIX_MODEL_LOADER_CONFIG + ".aai.";
- public static final String PREFIX_BABEL = PREFIX_MODEL_LOADER_CONFIG + ".babel.";
public static final String PREFIX_DEBUG = PREFIX_MODEL_LOADER_CONFIG + ".debug.";
private static final String SUFFIX_KEYSTORE_FILE = "KEYSTORE_FILE";
private static final String SUFFIX_KEYSTORE_PASS = "KEYSTORE_PASSWORD";
- private static final String SUFFIX_TRUSTSTORE_FILE = "TRUSTSTORE_FILE";
- private static final String SUFFIX_TRUSTSTORE_PASS = "TRUSTSTORE_PASSWORD";
-
// Configuration file properties
protected static final String PROP_ML_DISTRIBUTION_ACTIVE_SERVER_TLS_AUTH =
PREFIX_DISTRIBUTION_CLIENT + "ACTIVE_SERVER_TLS_AUTH";
protected static final String PROP_ML_DISTRIBUTION_SASL_JAAS_CONFIG = PREFIX_DISTRIBUTION_CLIENT + "SASL_JAAS_CONFIG";
protected static final String PROP_ML_DISTRIBUTION_SASL_MECHANISM = PREFIX_DISTRIBUTION_CLIENT + "SASL_MECHANISM";
protected static final String PROP_ML_DISTRIBUTION_SECURITY_PROTOCOL = PREFIX_DISTRIBUTION_CLIENT + "SECURITY_PROTOCOL";
- protected static final String PROP_AAI_BASE_URL = PREFIX_AAI + "BASE_URL";
- protected static final String PROP_AAI_KEYSTORE_FILE = PREFIX_AAI + SUFFIX_KEYSTORE_FILE;
- protected static final String PROP_AAI_KEYSTORE_PASSWORD = PREFIX_AAI + SUFFIX_KEYSTORE_PASS;
- protected static final String PROP_AAI_MODEL_RESOURCE_URL = PREFIX_AAI + "MODEL_URL";
- protected static final String PROP_AAI_NAMED_QUERY_RESOURCE_URL = PREFIX_AAI + "NAMED_QUERY_URL";
- protected static final String PROP_AAI_VNF_IMAGE_RESOURCE_URL = PREFIX_AAI + "VNF_IMAGE_URL";
- protected static final String PROP_AAI_AUTHENTICATION_USER = PREFIX_AAI + "AUTH_USER";
- protected static final String PROP_AAI_AUTHENTICATION_PASSWORD = PREFIX_AAI + "AUTH_PASSWORD";
- protected static final String PROP_AAI_USE_GIZMO = PREFIX_AAI + "USE_GIZMO";
- protected static final String PROP_AAI_USE_HTTPS = PREFIX_AAI + "USE_HTTPS";
- protected static final String PROP_BABEL_BASE_URL = PREFIX_BABEL + "BASE_URL";
- protected static final String PROP_BABEL_KEYSTORE_FILE = PREFIX_BABEL + SUFFIX_KEYSTORE_FILE;
- protected static final String PROP_BABEL_KEYSTORE_PASSWORD = PREFIX_BABEL + SUFFIX_KEYSTORE_PASS;
- protected static final String PROP_BABEL_TRUSTSTORE_FILE = PREFIX_BABEL + SUFFIX_TRUSTSTORE_FILE;
- protected static final String PROP_BABEL_TRUSTSTORE_PASSWORD = PREFIX_BABEL + SUFFIX_TRUSTSTORE_PASS;
- protected static final String PROP_BABEL_GENERATE_RESOURCE_URL = PREFIX_BABEL + "GENERATE_ARTIFACTS_URL";
- protected static final String PROP_BABEL_USE_HTTPS = PREFIX_BABEL + "USE_HTTPS";
protected static final String PROP_DEBUG_INGEST_SIMULATOR = PREFIX_DEBUG + "INGEST_SIMULATOR";
protected static final String FILESEP =
(System.getProperty("file.separator") == null) ? "/" : System.getProperty("file.separator");
- protected static final String PROP_AAI_CLIENT_CONNECT_TIMEOUT_MS = PREFIX_AAI + "RESTCLIENT_CONNECT_TIMEOUT";
- protected static final String PROP_AAI_CLIENT_READ_TIMEOUT_MS = PREFIX_AAI + "RESTCLIENT_READ_TIMEOUT";
-
private static String configHome;
private Properties modelLoaderProperties = null;
private String certLocation = ".";
return getIntegerPropertyOrZero(PROP_ML_DISTRIBUTION_HTTPS_PROXY_PORT);
}
- public String getAaiKeyStorePath() {
- return certLocation + File.separator + modelLoaderProperties.getProperty(PROP_AAI_KEYSTORE_FILE);
- }
-
- public String getBabelKeyStorePath() {
- String filename = get(PROP_BABEL_KEYSTORE_FILE);
- if (filename == null) {
- return null;
- } else {
- return certLocation + File.separator + filename;
- }
- }
-
- public String getAaiKeyStorePassword() {
- return getDeobfuscatedValue(get(PROP_AAI_KEYSTORE_PASSWORD));
- }
-
- public String getBabelKeyStorePassword() {
- return getDeobfuscatedValue(get(PROP_BABEL_KEYSTORE_PASSWORD));
- }
-
- public String getBabelTrustStorePath() {
- String filename = get(PROP_BABEL_TRUSTSTORE_FILE);
- if (filename == null) {
- return null;
- } else {
- return certLocation + File.separator + filename;
- }
- }
-
- public String getBabelTrustStorePassword() {
- return getDeobfuscatedValue(get(PROP_BABEL_TRUSTSTORE_PASSWORD));
- }
-
- public String getAaiBaseUrl() {
- return get(PROP_AAI_BASE_URL);
- }
-
- public String getBabelBaseUrl() {
- return get(PROP_BABEL_BASE_URL);
- }
-
- public String getBabelGenerateArtifactsUrl() {
- return get(PROP_BABEL_GENERATE_RESOURCE_URL);
- }
-
- public String getAaiModelUrl(String version) {
- setModelVersion(version);
- return updatePropertyOXMVersion(PROP_AAI_MODEL_RESOURCE_URL, version);
- }
-
- public String getAaiNamedQueryUrl(String version) {
- return updatePropertyOXMVersion(PROP_AAI_NAMED_QUERY_RESOURCE_URL, version);
- }
-
- public String getAaiVnfImageUrl() {
- return updatePropertyOXMVersion(PROP_AAI_VNF_IMAGE_RESOURCE_URL, getModelVersion());
- }
-
- public String getAaiAuthenticationUser() {
- return get(PROP_AAI_AUTHENTICATION_USER);
- }
public String getModelVersion() {
return modelVersion;
this.modelVersion = modelVersion;
}
- public boolean useGizmo() {
- String useGizmo = get(PROP_AAI_USE_GIZMO);
- return useGizmo != null && useGizmo.equalsIgnoreCase("true");
- }
-
- public boolean useHttpsWithAAI() {
- String useHttps = get(PROP_AAI_USE_HTTPS);
- return useHttps != null && useHttps.equalsIgnoreCase("true");
- }
-
- public boolean useHttpsWithBabel() {
- String useHttps = get(PROP_BABEL_USE_HTTPS);
- return useHttps != null && useHttps.equalsIgnoreCase("true");
- }
-
- /**
- * @return password for AAI authentication that has been reverse-engineered from its obfuscated form.
- */
- public String getAaiAuthenticationPassword() {
- String password = getDeobfuscatedValue(get(PROP_AAI_AUTHENTICATION_PASSWORD));
-
- if (password != null && password.isEmpty()) {
- password = null;
- }
-
- return password;
- }
-
/**
* @return a boolean value indicating whether the simulator is enabled.
*/
return propValue != null && "enabled".equalsIgnoreCase(propValue);
}
- /**
- * Read the value of the property and replace any wildcard OXM version "v*" with the supplied default OXM version
- *
- * @param propertyName
- * the name of the property storing the OXM version (possibly containing v*)
- * @param version
- * the default OXM version
- * @return the String value of the defined property (with any wildcard OXM version defaulted)
- */
- private String updatePropertyOXMVersion(String propertyName, String version) {
- String value = get(propertyName);
- if (version != null && value != null) {
- value = value.replace("v*", version);
- }
- return value;
- }
-
/**
* @return a boolean value indicating whether model loader is connected to ASDC.
*/
}
}
- public int getClientConnectTimeoutMs() {
- String connectTimeout = Optional.ofNullable(get(PROP_AAI_CLIENT_CONNECT_TIMEOUT_MS)).orElse("120000");
- return Integer.parseInt(connectTimeout);
- }
-
- public int getClientReadTimeoutMs() {
- String connectTimeout = Optional.ofNullable(get(PROP_AAI_CLIENT_READ_TIMEOUT_MS)).orElse("120000");
- return Integer.parseInt(connectTimeout);
- }
-
@Override
public String getKafkaSaslJaasConfig() {
String saslJaasConfFromEnv = System.getenv("SASL_JAAS_CONFIG");
package org.onap.aai.modelloader.entity;\r
\r
import java.util.List;\r
-import org.onap.aai.modelloader.config.ModelLoaderConfig;\r
+\r
+import org.onap.aai.modelloader.config.AaiProperties;\r
import org.onap.aai.modelloader.restclient.AaiRestClient;\r
\r
public abstract class ArtifactHandler {\r
\r
- protected ModelLoaderConfig config;\r
+ protected final AaiProperties aaiProperties;\r
\r
- protected ArtifactHandler(ModelLoaderConfig config) {\r
- this.config = config;\r
+ protected ArtifactHandler(AaiProperties aaiProperties) {\r
+ this.aaiProperties = aaiProperties;\r
}\r
\r
public abstract boolean pushArtifacts(List<Artifact> artifacts, String distributionId,\r
import org.apache.http.client.utils.URIBuilder;\r
import org.onap.aai.cl.api.Logger;\r
import org.onap.aai.cl.eelf.LoggerFactory;\r
-import org.onap.aai.modelloader.config.ModelLoaderConfig;\r
+import org.onap.aai.modelloader.config.AaiProperties;\r
import org.onap.aai.modelloader.entity.Artifact;\r
import org.onap.aai.modelloader.entity.ArtifactHandler;\r
import org.onap.aai.modelloader.entity.vnf.VnfImages;\r
\r
public static final String ATTR_UUID = "uuid";\r
\r
- public VnfCatalogArtifactHandler(ModelLoaderConfig config) {\r
- super(config);\r
+ public VnfCatalogArtifactHandler(AaiProperties aaiProperties) {\r
+ super(aaiProperties);\r
}\r
\r
/*\r
* (non-Javadoc)\r
- * \r
+ *\r
* @see org.openecomp.modelloader.entity.ArtifactHandler#pushArtifacts(java.util.List, java.lang.String)\r
*/\r
@Override\r
for (Artifact completedArtifact : completedArtifacts) {\r
Map<String, String> data = new Gson().fromJson(completedArtifact.getPayload(),\r
new TypeToken<Map<String, String>>() {}.getType());\r
- String url = config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "/vnf-image/" + data.get(ATTR_UUID);\r
+ String url = aaiProperties.getBaseUrl() + aaiProperties.getVnfImageUrl() + "/vnf-image/" + data.get(ATTR_UUID);\r
// Try to delete the image. If something goes wrong we can't really do anything here\r
aaiClient.getAndDeleteResource(url, distributionId);\r
}\r
\r
/**\r
* Build a VNF image from each of the supplied data items, and distribute to AAI\r
- * \r
+ *\r
* @param restClient\r
* @param distributionId\r
* @param completedArtifacts\r
private int getVnfImage(AaiRestClient restClient, String distributionId, String imageId,\r
Map<String, String> dataItem) throws VnfImageException {\r
try {\r
- URIBuilder b = new URIBuilder(config.getAaiBaseUrl() + config.getAaiVnfImageUrl());\r
+ URIBuilder b = new URIBuilder(aaiProperties.getBaseUrl() + aaiProperties.getVnfImageUrl());\r
for (Entry<String, String> entry : dataItem.entrySet()) {\r
b.addParameter(entry.getKey(), entry.getValue());\r
}\r
\r
// TODO: Get rid of the dataItem map and replace it with the VnfImage object\r
String payload = new Gson().toJson(dataItem);\r
- String putUrl = config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "/vnf-image/" + uuid;\r
+ String putUrl = aaiProperties.getBaseUrl() + aaiProperties.getVnfImageUrl() + "/vnf-image/" + uuid;\r
ResponseEntity<String> putResp =\r
restClient.putResource(putUrl, payload, distributionId, MediaType.APPLICATION_JSON, String.class);\r
return putResp != null && putResp.getStatusCode() == HttpStatus.CREATED;\r
\r
/**\r
* Parse the VNF Catalog XML and transform into Key/Value pairs.\r
- * \r
+ *\r
* @param vnfcArtifact\r
* @return VNF Image data in Map form\r
* @throws VnfImageException\r
import java.util.Set;
import org.onap.aai.cl.api.Logger;
import org.onap.aai.cl.eelf.LoggerFactory;
-import org.onap.aai.modelloader.config.ModelLoaderConfig;
+import org.onap.aai.modelloader.config.AaiProperties;
import org.onap.aai.modelloader.entity.Artifact;
import org.onap.aai.modelloader.entity.ArtifactType;
import org.onap.aai.modelloader.restclient.AaiRestClient;
public abstract String getUniqueIdentifier();
- public abstract boolean push(AaiRestClient aaiClient, ModelLoaderConfig config, String distId,
+ public abstract boolean push(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId,
List<Artifact> completedArtifacts);
- public abstract void rollbackModel(AaiRestClient aaiClient, ModelLoaderConfig config, String distId);
+ public abstract void rollbackModel(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId);
- protected boolean pushToGizmo(AaiRestClient aaiClient, ModelLoaderConfig config, String distId) {
+ protected boolean pushToGizmo(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId) {
try {
String gizmoPayload = GizmoTranslator.translate(getPayload());
// TODO: Use correct responseType here
- ResponseEntity<String> postResponse = aaiClient.postResource(config.getAaiBaseUrl().trim(), gizmoPayload, distId,
+ ResponseEntity<String> postResponse = aaiClient.postResource(aaiProperties.getBaseUrl().trim(), gizmoPayload, distId,
MediaType.APPLICATION_JSON, String.class);
if (postResponse.getStatusCode() != HttpStatus.OK) {
import org.onap.aai.cl.api.Logger;
import org.onap.aai.cl.eelf.LoggerFactory;
-import org.onap.aai.modelloader.config.ModelLoaderConfig;
+import org.onap.aai.modelloader.config.AaiProperties;
import org.onap.aai.modelloader.entity.Artifact;
import org.onap.aai.modelloader.entity.ArtifactType;
import org.onap.aai.modelloader.restclient.AaiRestClient;
}
@Override
- public boolean push(AaiRestClient aaiClient, ModelLoaderConfig config, String distId,
+ public boolean push(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId,
List<Artifact> completedArtifacts) {
- if (config.useGizmo()) {
- return pushToGizmo(aaiClient, config, distId);
+ if (aaiProperties.isUseGizmo()) {
+ return pushToGizmo(aaiClient, aaiProperties, distId);
}
- return pushToResources(aaiClient, config, distId, completedArtifacts);
+ return pushToResources(aaiClient, aaiProperties, distId, completedArtifacts);
}
- private boolean pushToResources(AaiRestClient aaiClient, ModelLoaderConfig config, String distId,
+ private boolean pushToResources(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId,
List<Artifact> completedArtifacts) {
boolean success = false;
// See whether the model is already present
- String resourceUrl = getModelUrl(config);
+ String resourceUrl = getModelUrl(aaiProperties);
// ResponseEntity<Model> result;
boolean modelExists = checkIfModelExists(aaiClient, distId, resourceUrl);
if(modelExists) {
- success = updateExistingModel(aaiClient, config, distId, completedArtifacts);
+ success = updateExistingModel(aaiClient, aaiProperties, distId, completedArtifacts);
} else {
success = createNewModel(aaiClient, distId, completedArtifacts, resourceUrl);
}
- // if (result != null) {
- // if (result.getStatusCode() == HttpStatus.OK) {
- // success = updateExistingModel(aaiClient, config, distId, completedArtifacts);
- // } else if (result.getStatusCode() == HttpStatus.NOT_FOUND) {
- // success = createNewModel(aaiClient, distId, completedArtifacts, resourceUrl);
- // } else {
- // logModelUpdateFailure(
- // "Response code " + result.getStatusCodeValue() + " invalid for getting resource model");
- // }
- // } else {
- // logModelUpdateFailure("Null response from RestClient");
- // }
-
return success;
}
logErrorMsg(FAILURE_MSG_PREFIX + getType() + " " + getUniqueIdentifier() + " " + message + ROLLBACK_MSG_SUFFIX);
}
- private boolean updateExistingModel(AaiRestClient aaiClient, ModelLoaderConfig config, String distId,
+ private boolean updateExistingModel(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId,
List<Artifact> completedArtifacts) {
boolean success;
logInfoMsg(getType() + " " + getModelInvariantId() + " already exists. Skipping ingestion.");
- success = pushModelVersion(aaiClient, config, distId, completedArtifacts);
+ success = pushModelVersion(aaiClient, aaiProperties, distId, completedArtifacts);
return success;
}
/**
* @param aaiClient
- * @param config
+ * @param aaiProperties
* @param distId
* @param completedArtifacts
* @return
*/
- private boolean pushModelVersion(AaiRestClient aaiClient, ModelLoaderConfig config, String distId,
+ private boolean pushModelVersion(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId,
List<Artifact> completedArtifacts) {
- if (xmlResourceCanBeFetched(aaiClient, distId, getModelVerUrl(config))) {
+ if (xmlResourceCanBeFetched(aaiClient, distId, getModelVerUrl(aaiProperties))) {
logInfoMsg(getType() + " " + getUniqueIdentifier() + " already exists. Skipping ingestion.");
return true;
}
// Load the model version
boolean success = true;
- success = putXmlResource(aaiClient, distId, getModelVerUrl(config), getModelVer());
+ success = putXmlResource(aaiClient, distId, getModelVerUrl(aaiProperties), getModelVer());
if (success) {
completedArtifacts.add(this);
logInfoMsg(getType() + " " + getUniqueIdentifier() + " successfully ingested.");
@Override
- public void rollbackModel(AaiRestClient aaiClient, ModelLoaderConfig config, String distId) {
+ public void rollbackModel(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId) {
// Gizmo is resilient and doesn't require a rollback. A redistribution will work fine even if
// the model is partially loaded.
- if (config.useGizmo()) {
+ if (aaiProperties.isUseGizmo()) {
return;
}
- String url = getModelVerUrl(config);
+ String url = getModelVerUrl(aaiProperties);
if (firstVersionOfModel) {
// If this was the first version of the model which was added, we want to remove the entire
// model rather than just the version.
- url = getModelUrl(config);
+ url = getModelUrl(aaiProperties);
}
// Best effort to delete. Nothing we can do in the event this fails.
aaiClient.getAndDeleteResource(url, distId);
}
- private String getModelUrl(ModelLoaderConfig config) {
- String baseURL = config.getAaiBaseUrl().trim();
- String subURL = config.getAaiModelUrl(getModelNamespaceVersion()).trim();
+ private String getModelUrl(AaiProperties aaiProperties) {
+ String baseURL = aaiProperties.getBaseUrl().trim();
+ String subURL = String.format(aaiProperties.getModelUrl(), getModelNamespaceVersion()).trim();
String instance = getModelInvariantId();
if (!baseURL.endsWith("/") && !subURL.startsWith("/")) {
return baseURL + subURL + instance;
}
- private String getModelVerUrl(ModelLoaderConfig config) {
- String baseURL = config.getAaiBaseUrl().trim();
- String subURL = config.getAaiModelUrl(getModelNamespaceVersion()).trim() + getModelInvariantId()
+ private String getModelVerUrl(AaiProperties aaiProperties) {
+ String baseURL = aaiProperties.getBaseUrl().trim();
+ String subURL = String.format(aaiProperties.getModelUrl(), getModelNamespaceVersion()).trim() + getModelInvariantId()
+ AAI_MODEL_VER_SUB_URL;
String instance = getModelVerId();
import java.util.List;
import org.onap.aai.cl.api.Logger;
import org.onap.aai.cl.eelf.LoggerFactory;
-import org.onap.aai.modelloader.config.ModelLoaderConfig;
+import org.onap.aai.modelloader.config.AaiProperties;
import org.onap.aai.modelloader.entity.Artifact;
import org.onap.aai.modelloader.entity.ArtifactHandler;
import org.onap.aai.modelloader.restclient.AaiRestClient;
private static Logger logger = LoggerFactory.getInstance().getLogger(ModelArtifactHandler.class.getName());
- public ModelArtifactHandler(ModelLoaderConfig config) {
- super(config);
+ public ModelArtifactHandler(AaiProperties aaiProperties) {
+ super(aaiProperties);
}
@Override
// Push the ordered list of model artifacts to A&AI. If one fails, we need to roll back the changes.
for (Artifact art : sortedModelArtifacts) {
AbstractModelArtifact model = (AbstractModelArtifact) art;
- if (!model.push(aaiClient, config, distributionID, completedArtifacts)) {
+ if (!model.push(aaiClient, aaiProperties, distributionID, completedArtifacts)) {
return false;
}
}
public void rollback(List<Artifact> completedArtifacts, String distributionId, AaiRestClient aaiClient) {
for (Artifact artifactToDelete : completedArtifacts) {
AbstractModelArtifact model = (AbstractModelArtifact) artifactToDelete;
- model.rollbackModel(aaiClient, config, distributionId);
+ model.rollbackModel(aaiClient, aaiProperties, distributionId);
}
}
}
import java.util.List;
-import org.onap.aai.modelloader.config.ModelLoaderConfig;
import org.onap.aai.modelloader.entity.ArtifactType;
import org.onap.aai.modelloader.restclient.AaiRestClient;
-
+import org.onap.aai.modelloader.config.AaiProperties;
import org.onap.aai.modelloader.entity.Artifact;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
}
@Override
- public boolean push(AaiRestClient aaiClient, ModelLoaderConfig config, String distId, List<Artifact> completedArtifacts) {
- if (config.useGizmo()) {
- return pushToGizmo(aaiClient, config, distId);
+ public boolean push(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId, List<Artifact> completedArtifacts) {
+ if (aaiProperties.isUseGizmo()) {
+ return pushToGizmo(aaiClient, aaiProperties, distId);
}
- return pushToResources(aaiClient, config, distId, completedArtifacts);
+ return pushToResources(aaiClient, aaiProperties, distId, completedArtifacts);
}
- private boolean pushToResources(AaiRestClient aaiClient, ModelLoaderConfig config, String distId,
+ private boolean pushToResources(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId,
List<Artifact> completedArtifacts) {
ResponseEntity<String> getResponse =
- aaiClient.getResource(getNamedQueryUrl(config), distId, MediaType.APPLICATION_XML, String.class);
+ aaiClient.getResource(getNamedQueryUrl(aaiProperties), distId, MediaType.APPLICATION_XML, String.class);
if (getResponse == null || getResponse.getStatusCode() != HttpStatus.OK) {
// Only attempt the PUT if the model doesn't already exist
- ResponseEntity<String> putResponse = aaiClient.putResource(getNamedQueryUrl(config), getPayload(), distId,
+ ResponseEntity<String> putResponse = aaiClient.putResource(getNamedQueryUrl(aaiProperties), getPayload(), distId,
MediaType.APPLICATION_XML, String.class);
if (putResponse != null && putResponse.getStatusCode() == HttpStatus.CREATED) {
completedArtifacts.add(this);
}
@Override
- public void rollbackModel(AaiRestClient aaiClient, ModelLoaderConfig config, String distId) {
- // Gizmo is resilient and doesn't require a rollback. A redistribution will work fine even if
+ public void rollbackModel(AaiRestClient aaiClient, AaiProperties aaiProperties, String distId) {
+ // Gizmo is resilient and doesn't require a rollback. A redistribution will work fine even if
// the model is partially loaded.
- if (config.useGizmo()) {
+ if (aaiProperties.isUseGizmo()) {
return;
}
-
+
// Best effort to delete. Nothing we can do in the event this fails.
- aaiClient.getAndDeleteResource(getNamedQueryUrl(config), distId);
+ aaiClient.getAndDeleteResource(getNamedQueryUrl(aaiProperties), distId);
}
- private String getNamedQueryUrl(ModelLoaderConfig config) {
- String baseURL = config.getAaiBaseUrl().trim();
- String subURL = config.getAaiNamedQueryUrl(getModelNamespaceVersion()).trim();
+ private String getNamedQueryUrl(AaiProperties aaiProperties) {
+ String baseURL = aaiProperties.getBaseUrl().trim();
+ String subURL = String.format(aaiProperties.getNamedQueryUrl(), getModelNamespaceVersion()).trim();
String instance = this.getNamedQueryUuid();
if (!baseURL.endsWith("/") && !subURL.startsWith("/")) {
List<Artifact> vnfcFiles = new ArrayList<>();
try (SeekableInMemoryByteChannel inMemoryByteChannel = new SeekableInMemoryByteChannel(archive);
- ZipFile zipFile = new ZipFile(inMemoryByteChannel)) {
+ ZipFile zipFile = ZipFile.builder().setSeekableByteChannel(inMemoryByteChannel).get()) {
for (Enumeration<ZipArchiveEntry> enumeration = zipFile.getEntries(); enumeration.hasMoreElements();) {
ZipArchiveEntry entry = enumeration.nextElement();
if (fileShouldBeExtracted(entry)) {
return extractFile;
}
}
-
import java.util.Collections;
import org.onap.aai.cl.api.Logger;
import org.onap.aai.cl.eelf.LoggerFactory;
-import org.onap.aai.modelloader.config.ModelLoaderConfig;
+import org.onap.aai.modelloader.config.AaiProperties;
import org.onap.aai.modelloader.entity.AaiResourcesObject;
import org.onap.aai.modelloader.service.ModelLoaderMsgs;
import org.springframework.http.HttpEntity;
@Component
public class AaiRestClient {
+ private final AaiProperties aaiProperties;
+
private static Logger logger = LoggerFactory.getInstance().getLogger(AaiRestClient.class.getName());
public static final String HEADER_TRANS_ID = "X-TransactionId";
public static final String HEADER_FROM_APP_ID = "X-FromAppId";
public static final String ML_APP_NAME = "ModelLoader";
private static final String RESOURCE_VERSION_PARAM = "resource-version";
- private final ModelLoaderConfig config;
private final RestTemplate restTemplate;
- public AaiRestClient(ModelLoaderConfig config, RestTemplate restTemplate) {
- this.config = config;
+ public AaiRestClient(AaiProperties aaiProperties, RestTemplate restTemplate) {
+ this.aaiProperties = aaiProperties;
this.restTemplate = restTemplate;
}
private boolean useBasicAuth() {
- return config.getAaiAuthenticationUser() != null && config.getAaiAuthenticationPassword() != null;
+ return aaiProperties.getAuthUser() != null && aaiProperties.getAuthPassword() != null;
}
/**
* Create the HTTP headers required for an A&AI operation (GET/POST/PUT/DELETE)
- *
+ *
* @param transId
* @return map of headers
*/
headers.set(AaiRestClient.HEADER_TRANS_ID, transId);
headers.set(AaiRestClient.HEADER_FROM_APP_ID, AaiRestClient.ML_APP_NAME);
if (useBasicAuth()) {
- headers.setBasicAuth(config.getAaiAuthenticationUser(), config.getAaiAuthenticationPassword());
+ headers.setBasicAuth(aaiProperties.getAuthUser(), aaiProperties.getAuthPassword());
}
return headers;
}
import org.onap.aai.babel.service.data.BabelRequest;
import org.onap.aai.cl.api.Logger;
import org.onap.aai.cl.eelf.LoggerFactory;
-import org.onap.aai.modelloader.config.ModelLoaderConfig;
+import org.onap.aai.modelloader.config.BabelProperties;
import org.onap.aai.modelloader.service.ModelLoaderMsgs;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
+import lombok.RequiredArgsConstructor;
+
/**
* HTTPS Client for interfacing with Babel.
*
*/
@Component
+@RequiredArgsConstructor
public class BabelServiceClientImpl implements BabelServiceClient {
private static final Logger logger = LoggerFactory.getInstance().getLogger(BabelServiceClientImpl.class);
- private final ModelLoaderConfig config;
+ private final BabelProperties babelProperties;
private final RestTemplate restTemplate;
- public BabelServiceClientImpl(ModelLoaderConfig config, RestTemplate restTemplate) {
- this.config = config;
- this.restTemplate = restTemplate;
- }
-
@Override
public List<BabelArtifact> postArtifact(BabelRequest babelRequest, String transactionId) throws BabelServiceClientException {
if (logger.isDebugEnabled()) {
+ " Artifact version: " + babelRequest.getArtifactVersion() + " Artifact payload: " + babelRequest.getCsar());
}
- String resourceUrl = config.getBabelBaseUrl() + config.getBabelGenerateArtifactsUrl();
+ String resourceUrl = babelProperties.getBaseUrl() + babelProperties.getGenerateArtifactsUrl();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
logging.config=${logback.configurationFile}
management.endpoints.web.exposure.include=*
+
+ml.babel.base-url=https://<BABEL_HOST>:9516
+ml.babel.generate-artifacts-url=/services/babel-service/v1/app/generateArtifacts
+
+# Model Loader Client Configuration for the A&AI REST interface
+ml.aai.base-url=https://<AAI_HOST>:8443
+ml.aai.model-url=/aai/%s/service-design-and-creation/models/model/
+ml.aai.named-query-url=/aai/%s/service-design-and-creation/named-queries/named-query/
+ml.aai.vnf-image-url=/aai/v*/service-design-and-creation/vnf-images # v* is supported by the resources api and translates to 'latest'
+ml.aai.auth-user=ModelLoader
+ml.aai.auth-password=
+ml.aai.use-gizmo=false
}
private void setOverrides(Properties configProperties) {
- configProperties.setProperty("ml.babel.BASE_URL", "http://localhost:" + wiremockPort);
+ configProperties.setProperty("ml.babel.base-url", "http://localhost:" + wiremockPort);
}
}
--- /dev/null
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2025 Deutsche Telekom AG 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.onap.aai.modelloader.config;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest(properties = {
+ "ml.babel.generate-artifacts-url=/foo"
+})
+public class PropertiesTest {
+
+ @Autowired
+ BabelProperties babelProperties;
+
+ @Test
+ void thatBabelPropertiesBindingWorks() {
+ assertEquals("/foo", babelProperties.getGenerateArtifactsUrl());
+ }
+
+}
import static org.junit.jupiter.api.Assertions.assertEquals;
-import java.io.File;
import java.util.List;
import java.util.Properties;
import org.eclipse.jetty.util.security.Password;
ModelLoaderConfig config =
createObfuscatedTestConfig(ModelLoaderConfig.PROP_ML_DISTRIBUTION_PASSWORD, password);
assertEquals(password, config.getPassword());
-
+
config = createUnobfuscatedTestConfig(ModelLoaderConfig.PROP_ML_DISTRIBUTION_PASSWORD, password);
assertEquals(password, config.getPassword());
}
ModelLoaderConfig config =
createObfuscatedTestConfig(ModelLoaderConfig.PROP_ML_DISTRIBUTION_KEYSTORE_PASSWORD, password);
assertEquals(password, config.getKeyStorePassword());
-
+
config = createUnobfuscatedTestConfig(ModelLoaderConfig.PROP_ML_DISTRIBUTION_KEYSTORE_PASSWORD, password);
assertEquals(password, config.getKeyStorePassword());
}
- @Test
- public void testDecryptAaiAuthenticationPassword() {
- String password = "myvoiceismypassword";
- ModelLoaderConfig config =
- createObfuscatedTestConfig(ModelLoaderConfig.PROP_AAI_AUTHENTICATION_PASSWORD, password);
- assertEquals(password, config.getAaiAuthenticationPassword());
-
- config = createUnobfuscatedTestConfig(ModelLoaderConfig.PROP_AAI_AUTHENTICATION_PASSWORD, password);
- assertEquals(password, config.getAaiAuthenticationPassword());
- }
-
- @Test
- public void testDecryptAaiKeystorePassword() {
- String password = "myvoiceismypassword";
- ModelLoaderConfig config = createObfuscatedTestConfig(ModelLoaderConfig.PROP_AAI_KEYSTORE_PASSWORD, password);
- assertEquals(password, config.getAaiKeyStorePassword());
-
- config = createUnobfuscatedTestConfig(ModelLoaderConfig.PROP_AAI_KEYSTORE_PASSWORD, password);
- assertEquals(password, config.getAaiKeyStorePassword());
- }
-
- @Test
- public void testAaiBaseUrl() {
- String url = "http://localhost:1234/";
- Properties props = new Properties();
- props.put(ModelLoaderConfig.PROP_AAI_BASE_URL, url);
- ModelLoaderConfig config = new ModelLoaderConfig(props, null);
- assertEquals(url, config.getAaiBaseUrl());
- }
-
- @Test
- public void testDecryptBabelKeystorePassword() {
- String password = "babelpassword";
- ModelLoaderConfig config = createObfuscatedTestConfig(ModelLoaderConfig.PROP_BABEL_KEYSTORE_PASSWORD, password);
- assertEquals(password, config.getBabelKeyStorePassword());
-
- config = createUnobfuscatedTestConfig(ModelLoaderConfig.PROP_BABEL_KEYSTORE_PASSWORD, password);
- assertEquals(password, config.getBabelKeyStorePassword());
- }
-
- @Test
- public void testBabelKeystorePath() {
- String root = "path_to_keystore";
- String path = "relative_keystore_path";
- Properties props = new Properties();
- props.put(ModelLoaderConfig.PROP_BABEL_KEYSTORE_FILE, path);
- ModelLoaderConfig config = new ModelLoaderConfig(props, root);
- assertEquals(root + File.separator + path, config.getBabelKeyStorePath());
- }
-
- @Test
- public void testBabelBaseUrl() {
- String url = "http://localhost/";
- Properties props = new Properties();
- props.put(ModelLoaderConfig.PROP_BABEL_BASE_URL, url);
- ModelLoaderConfig config = new ModelLoaderConfig(props, null);
- assertEquals(url, config.getBabelBaseUrl());
- }
-
- @Test
- public void testBabelGenerateArtifactsUrl() {
- String url = "/path/to/the/resource";
- Properties props = new Properties();
- props.put(ModelLoaderConfig.PROP_BABEL_GENERATE_RESOURCE_URL, url);
- ModelLoaderConfig config = new ModelLoaderConfig(props, null);
- assertEquals(url, config.getBabelGenerateArtifactsUrl());
- }
-
- @Test
- public void testGetUrls() {
- Properties props = new Properties();
- props.put(ModelLoaderConfig.PROP_AAI_MODEL_RESOURCE_URL, "/aai/v*/service-design-and-creation/models/model/");
- props.put(ModelLoaderConfig.PROP_AAI_NAMED_QUERY_RESOURCE_URL,
- "/aai/v*/service-design-and-creation/named-queries/named-query/");
- ModelLoaderConfig config = new ModelLoaderConfig(props, null);
-
- assertEquals("/aai/v9/service-design-and-creation/models/model/", config.getAaiModelUrl("v9"));
- assertEquals("/aai/v10/service-design-and-creation/named-queries/named-query/",
- config.getAaiNamedQueryUrl("v10"));
- }
-
/**
* Create a Model Loader Configuration object from the supplied Property.
- *
+ *
* @param propertyName property key
* @param propertyValue value of the property
* @return a new ModelLoaderConfig object containing a single obfuscated property value
props.put(propertyName, Password.obfuscate(propertyValue));
return new ModelLoaderConfig(props, null);
}
-
+
private ModelLoaderConfig createUnobfuscatedTestConfig(String propertyName, String propertyValue) {
Properties props = new Properties();
props.put(propertyName, propertyValue);
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
-import java.util.Properties;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
-import org.onap.aai.modelloader.config.ModelLoaderConfig;
+import org.onap.aai.modelloader.config.AaiProperties;
import org.onap.aai.modelloader.entity.Artifact;
import org.onap.aai.modelloader.entity.ArtifactType;
import org.onap.aai.modelloader.restclient.AaiRestClient;
public class TestVnfCatalogArtifactHandler {
- protected static String CONFIG_FILE = "model-loader.properties";
+ protected static AaiProperties aaiProperties = new AaiProperties();
private AaiRestClient mockRestClient = mock(AaiRestClient.class);
+ @BeforeAll
+ public static void setup() {
+ aaiProperties.setBaseUrl("http://aai.onap:80");
+ aaiProperties.setModelUrl("/aai/%s/service-design-and-creation/models/model/");
+ aaiProperties.setNamedQueryUrl("/aai/%s/service-design-and-creation/named-queries/named-query/");
+ aaiProperties.setVnfImageUrl("/aai/v*/service-design-and-creation/vnf-images");
+ }
+
/**
* Update A&AI with 4 images, 2 of which already exist.
- *
+ *
* @throws Exception
*/
@Test
mockPutOperations();
// Example VNF Catalog XML
- VnfCatalogArtifactHandler handler = new VnfCatalogArtifactHandler(createConfig());
+ VnfCatalogArtifactHandler handler = new VnfCatalogArtifactHandler(aaiProperties);
assertTrue(handler.pushArtifacts(createVnfCatalogArtifact(), "test", new ArrayList<Artifact>(), mockRestClient));
assertPutOperationsSucceeded();
mockPutOperations();
// Example VNF Catalog XML
- VnfCatalogArtifactHandler handler = new VnfCatalogArtifactHandler(createConfig());
+ VnfCatalogArtifactHandler handler = new VnfCatalogArtifactHandler(aaiProperties);
assertThat(
handler.pushArtifacts(createVnfCatalogXmlArtifact(), "test", new ArrayList<Artifact>(), mockRestClient),
is(true));
assertThat(argument.getAllValues().get(1), containsString("VM00"));
}
- private ModelLoaderConfig createConfig() {
- Properties configProperties = new Properties();
- try {
- configProperties.load(this.getClass().getClassLoader().getResourceAsStream(CONFIG_FILE));
- } catch (IOException e) {
- fail();
- }
- ModelLoaderConfig config = new ModelLoaderConfig(configProperties, null);
- return config;
- }
-
/**
* Example VNF Catalog based on JSON data (returned by Babel)
- *
+ *
* @return test Artifacts
* @throws IOException
* @throws UnsupportedEncodingException
/**
* Example VNF Catalog based on VNF_CATALOG XML
- *
+ *
* @return test Artifacts
* @throws IOException
* @throws UnsupportedEncodingException
import java.util.Collections;
import java.util.List;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.onap.aai.modelloader.config.AaiProperties;
import org.onap.aai.modelloader.config.ModelLoaderConfig;
import org.onap.aai.modelloader.entity.Artifact;
import org.onap.aai.modelloader.restclient.AaiRestClient;
@Mock
private AaiRestClient aaiClient;
+ private static AaiProperties aaiProperties = new AaiProperties();
+
+ @BeforeAll
+ public static void setup() {
+ aaiProperties.setBaseUrl("http://aai.onap:80");
+ aaiProperties.setModelUrl("/aai/%s/service-design-and-creation/models/model/");
+ aaiProperties.setNamedQueryUrl("/aai/%s/service-design-and-creation/named-queries/named-query/");
+ aaiProperties.setVnfImageUrl("/aai/%s/service-design-and-creation/vnf-images");
+ }
+
@BeforeEach
public void setupMocks() {
MockitoAnnotations.openMocks(this);
@Test
public void testEmptyLists() {
- ModelArtifactHandler handler = new ModelArtifactHandler(config);
+ ModelArtifactHandler handler = new ModelArtifactHandler(aaiProperties);
handler.pushArtifacts(Collections.emptyList(), "", Collections.emptyList(), aaiClient);
handler.rollback(Collections.emptyList(), "", aaiClient);
assertTrue(true);
@Test
public void testPushExistingModelsWithRollback() {
- when(config.getAaiBaseUrl()).thenReturn("");
- when(config.getAaiModelUrl(any())).thenReturn("");
-
ResponseEntity operationResult = mock(ResponseEntity.class);
when(aaiClient.getResource(any(), any(), any(), any())).thenReturn(operationResult);
when(operationResult.getStatusCode()).thenReturn(HttpStatus.OK);
Artifact artifact = new ModelArtifact();
artifacts.add(artifact);
- ModelArtifactHandler handler = new ModelArtifactHandler(config);
+ ModelArtifactHandler handler = new ModelArtifactHandler(aaiProperties);
boolean pushed = handler.pushArtifacts(artifacts, "", Collections.emptyList(), aaiClient);
assertTrue(pushed);
handler.rollback(artifacts, "", aaiClient);
@Test
public void testPushNewModelsWithRollback() {
- when(config.getAaiBaseUrl()).thenReturn("");
- when(config.getAaiModelUrl(any())).thenReturn("");
- when(config.getAaiNamedQueryUrl(any())).thenReturn("");
-
ResponseEntity getResult = mock(ResponseEntity.class);
when(aaiClient.getResource(any(), any(), any(), any())).thenReturn(getResult);
when(getResult.getStatusCode()).thenReturn(HttpStatus.NOT_FOUND);
artifacts.add(namedQueryArtifact);
List<Artifact> completedArtifacts = new ArrayList<>();
- ModelArtifactHandler handler = new ModelArtifactHandler(config);
+ ModelArtifactHandler handler = new ModelArtifactHandler(aaiProperties);
boolean pushed = handler.pushArtifacts(artifacts, "", completedArtifacts, aaiClient);
assertThat(pushed, is(true));
handler.rollback(artifacts, "", aaiClient);
@Test
public void testPushNewModelsBadRequest() {
- when(config.getAaiBaseUrl()).thenReturn("");
- when(config.getAaiModelUrl(any())).thenReturn("");
- when(config.getAaiNamedQueryUrl(any())).thenReturn("");
-
ResponseEntity getResult = mock(ResponseEntity.class);
when(aaiClient.getResource(any(), any(), any(), any())).thenReturn(getResult);
when(getResult.getStatusCode()).thenReturn(HttpStatus.NOT_FOUND);
@Test
public void testBadRequestResourceModelResult() {
- when(config.getAaiBaseUrl()).thenReturn("");
- when(config.getAaiModelUrl(any())).thenReturn("");
-
ResponseEntity operationResult = mock(ResponseEntity.class);
when(aaiClient.getResource(any(), any(), any(), any())).thenReturn(operationResult);
when(operationResult.getStatusCode()).thenReturn(HttpStatus.BAD_REQUEST);
}
private void checkRollback(List<Artifact> artifacts) {
- ModelArtifactHandler handler = new ModelArtifactHandler(config);
+ ModelArtifactHandler handler = new ModelArtifactHandler(aaiProperties);
boolean pushed = handler.pushArtifacts(artifacts, "", Collections.emptyList(), aaiClient);
assertThat(pushed, is(false));
handler.rollback(artifacts, "", aaiClient);
}
}
-
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
+import org.onap.aai.modelloader.config.AaiProperties;
import org.onap.aai.modelloader.config.ModelLoaderConfig;
import org.onap.aai.modelloader.entity.Artifact;
import org.onap.aai.modelloader.entity.model.ModelArtifact;
final ObjectMapper objectMapper = new ObjectMapper();
@Mock
- ModelLoaderConfig config;
+ AaiProperties aaiProperties;
@InjectMocks
ModelArtifactHandler modelArtifactHandler;
@BeforeEach
public void setUp() {
- when(config.getAaiBaseUrl()).thenReturn("http://localhost:" + wiremockPort);
- when(config.getAaiModelUrl(any())).thenReturn("/aai/v28/service-design-and-creation/models/model/");
+ when(aaiProperties.getBaseUrl()).thenReturn("http://localhost:" + wiremockPort);
+ when(aaiProperties.getModelUrl()).thenReturn("/aai/%s/service-design-and-creation/models/model/");
}
@Test
ModelArtifact modelArtifact = new ModelArtifact();
modelArtifact.setModelInvariantId("modelInvariantId");
+ modelArtifact.setModelNamespace("v28");
modelArtifact.setPayload("");
List<Artifact> artifacts = List.of(modelArtifact);
List<Artifact> completedArtifacts = new ArrayList<>();
ModelArtifact modelArtifact = new ModelArtifact();
modelArtifact.setModelInvariantId("modelInvariantId");
modelArtifact.setModelVerId("modelVersionId");
+ modelArtifact.setModelNamespace("v28");
modelArtifact.setPayload("");
modelArtifact.setModelVer("2.0");
List<Artifact> artifacts = List.of(modelArtifact);
@Test
public void thatModelCanBeRolledBack() {
stubFor(WireMock.get(urlEqualTo("/aai/v28/service-design-and-creation/models/model/3a40ab73-6694-4e75-bb6d-9a4a86ce35b3"))
- .withHeader("Accept", equalTo(MediaType.APPLICATION_XML_VALUE))
+ .withHeader("Accept", equalTo(MediaType.APPLICATION_XML_VALUE))
.withHeader("X-FromAppId", equalTo("ModelLoader"))
.withHeader("X-TransactionId", equalTo("distributionId"))
.willReturn(aResponse()
ModelArtifact modelArtifact = new ModelArtifact();
modelArtifact.setModelInvariantId("3a40ab73-6694-4e75-bb6d-9a4a86ce35b3");
modelArtifact.setModelVerId("modelVersionId");
- // modelArtifact.setModelVer("2.0");
-
+ modelArtifact.setModelNamespace("v28");
+
List<Artifact> completedArtifacts = new ArrayList<>();
completedArtifacts.add(modelArtifact);
AaiRestClient aaiClient = Mockito.mock(AaiRestClient.class);
when(aaiClient.putResource(any(), any(), any(), any(), any())).thenReturn(createdResult);
when(aaiClient.getResource(any(), any(), any(), any())).thenReturn(notFoundResult);
- modelArtifact.push(aaiClient, config, null, new ArrayList<>());
+ modelArtifact.push(aaiClient, aaiProperties, null, new ArrayList<>());
}
@Test
ModelArtifact modelArtifact = new ModelArtifact();
modelArtifact.setModelInvariantId("modelInvariantId");
modelArtifact.setModelVerId("modelVersionId");
-
+ modelArtifact.setModelNamespace("v28");
+
List<Artifact> completedArtifacts = new ArrayList<>();
completedArtifacts.add(modelArtifact);
deleteRequestedFor(
urlEqualTo("/aai/v28/service-design-and-creation/models/model/modelInvariantId/model-vers/model-ver/modelVersionId?resource-version=1708937324692")));
}
-}
\ No newline at end of file
+}
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-import java.util.Properties;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.onap.aai.babel.service.data.BabelArtifact;
-import org.onap.aai.modelloader.config.ModelLoaderConfig;
+import org.onap.aai.modelloader.config.AaiProperties;
import org.onap.aai.modelloader.entity.Artifact;
import org.onap.aai.modelloader.entity.catalog.VnfCatalogArtifact;
import org.onap.aai.modelloader.entity.catalog.VnfCatalogArtifactHandler;
*/
public class TestArtifactDeploymentManager {
- private static final String CONFIG_FILE = "model-loader.properties";
private static final String SHOULD_HAVE_RETURNED_FALSE = "This should have returned false";
- private Properties configProperties;
private ArtifactDeploymentManager manager;
@Mock private ModelArtifactHandler modelArtifactHandlerMock;
@BeforeEach
public void setup() throws IOException {
MockitoAnnotations.openMocks(this);
- configProperties = new Properties();
- configProperties.load(this.getClass().getClassLoader().getResourceAsStream(CONFIG_FILE));
+ AaiProperties aaiProperties = new AaiProperties();
+ aaiProperties.setBaseUrl("http://aai.onap:80");
+ aaiProperties.setModelUrl("/aai/%s/service-design-and-creation/models/model/");
+ aaiProperties.setNamedQueryUrl("/aai/%s/service-design-and-creation/named-queries/named-query/");
+ aaiProperties.setVnfImageUrl("/aai/%s/service-design-and-creation/vnf-images");
- ModelLoaderConfig modelLoaderConfig = new ModelLoaderConfig(configProperties, null);
- AaiRestClient aaiRestClient = new AaiRestClient(modelLoaderConfig, new RestTemplate());
+ AaiRestClient aaiRestClient = new AaiRestClient(aaiProperties, new RestTemplate());
manager = new ArtifactDeploymentManager(modelArtifactHandlerMock, vnfCatalogArtifactHandlerMock, aaiRestClient);
}
@AfterEach
public void tearDown() {
- configProperties = null;
modelArtifactHandlerMock = null;
vnfCatalogArtifactHandlerMock = null;
manager = null;
/**
* Deploy both models and VNF images.
- *
+ *
* @throws IOException
* @throws BabelArtifactParsingException
* @throws InvalidArchiveException
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
-import java.util.Properties;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import javax.xml.parsers.DocumentBuilderFactory;
-import org.onap.aai.modelloader.config.ModelLoaderConfig;
+import org.onap.aai.modelloader.config.AaiProperties;
import org.onap.aai.modelloader.entity.ArtifactType;
import org.onap.aai.modelloader.entity.model.ModelArtifact;
import org.onap.aai.modelloader.entity.model.ModelArtifactParser;
// This test requires a running A&AI system. To test locally, annotate with org.junit.Test
public void testRestClient() throws Exception {
- Properties props = new Properties();
- props.setProperty("ml.distribution.ARTIFACT_TYPES", "MODEL_INVENTORY_PROFILE,MODEL_QUERY_SPEC,VNF_CATALOG");
- props.setProperty("ml.aai.BASE_URL", "https://localhost:8443");
- props.setProperty("ml.aai.MODEL_URL", "/aai/v9/service-design-and-creation/models/model/");
-
- ModelLoaderConfig config = new ModelLoaderConfig(props, ".");
+ AaiProperties aaiProperties = new AaiProperties();
+ aaiProperties.setBaseUrl("http://aai.onap:80");
+ aaiProperties.setModelUrl("/aai/%s/service-design-and-creation/models/model/");
+ aaiProperties.setNamedQueryUrl("/aai/%s/service-design-and-creation/named-queries/named-query/");
+ aaiProperties.setVnfImageUrl("/aai/%s/service-design-and-creation/vnf-images");
File xmlFile = new File(MODEL_FILE);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
model.setPayload(readFile(MODEL_FILE));
model.setModelNamespace("http://org.openecomp.aai.inventory/v9");
- AaiRestClient aaiClient = new AaiRestClient(config, new RestTemplate());
+ AaiRestClient aaiClient = new AaiRestClient(aaiProperties, new RestTemplate());
// GET model
ResponseEntity opResult =
- aaiClient.getResource(getUrl(model, config), "example-trans-id-0", MediaType.APPLICATION_XML, String.class);
+ aaiClient.getResource(getUrl(model, aaiProperties), "example-trans-id-0", MediaType.APPLICATION_XML, String.class);
assertEquals(opResult.getStatusCode(), HttpStatus.NOT_FOUND);
// PUT the model
- opResult = aaiClient.putResource(getUrl(model, config), model.getPayload(), "example-trans-id-1",
+ opResult = aaiClient.putResource(getUrl(model, aaiProperties), model.getPayload(), "example-trans-id-1",
MediaType.APPLICATION_XML, String.class);
assertEquals(opResult.getStatusCode(), HttpStatus.CREATED);
// DELETE the model
- opResult = aaiClient.getAndDeleteResource(getUrl(model, config), "example-trans-id-3");
+ opResult = aaiClient.getAndDeleteResource(getUrl(model, aaiProperties), "example-trans-id-3");
assertEquals(opResult.getStatusCode(), HttpStatus.NO_CONTENT);
} catch (Exception e) {
e.printStackTrace();
return new String(encoded);
}
- private String getUrl(ModelArtifact model, ModelLoaderConfig config) {
+ private String getUrl(ModelArtifact model, AaiProperties aaiProperties) {
String subUrl;
if (model.getType().equals(ArtifactType.MODEL)) {
- subUrl = config.getAaiModelUrl(model.getModelNamespaceVersion()).trim();
+ subUrl = String.format(aaiProperties.getModelUrl(), model.getModelNamespaceVersion()).trim();
} else {
- subUrl = config.getAaiNamedQueryUrl(model.getModelNamespaceVersion()).trim();
+ subUrl = String.format(aaiProperties.getNamedQueryUrl(), model.getModelNamespaceVersion()).trim();
}
- String baseUrl = config.getAaiBaseUrl().trim();
+ String baseUrl = aaiProperties.getBaseUrl().trim();
if (!baseUrl.endsWith("/") && !subUrl.startsWith("/")) {
baseUrl = baseUrl + "/";
}
CONFIG_HOME=src/test/resources
spring.kafka.consumer.auto-offset-reset=earliest
spring.kafka.consumer.group-id=aai
-spring.kafka.consumer.client-id=aai-model-loader
+spring.kafka.consumer.client-id=aai-model-loader
topics.distribution.notification=SDC-DISTR-NOTIF-TOPIC-AUTO
spring.sleuth.enabled=false
ml.distribution.connection.enabled=false # avoid having the distribution client running in the background (requires active kafka)
+ml.babel.generate-artifacts-url=/services/babel-service/v1/app/generateArtifacts
+ml.babel.base-url=http://localhost:${wiremock.server.port}
-spring.main.allow-bean-definition-overriding=true
\ No newline at end of file
+spring.main.allow-bean-definition-overriding=true
# Disable ASDC polling & enable REST interface
ml.distribution.ASDC_CONNECTION_DISABLE=true
ml.debug.INGEST_SIMULATOR=enabled
-
-# Model Loader Client Configuration for the A&AI REST interface
-ml.aai.BASE_URL=https://localhost:8443
-ml.aai.MODEL_URL=/aai/v*/service-design-and-creation/models/model/
-ml.aai.NAMED_QUERY_URL=/aai/v*/service-design-and-creation/named-queries/named-query/
-ml.aai.VNF_IMAGE_URL=/aai/v*/service-design-and-creation/vnf-images
-ml.aai.KEYSTORE_FILE=aai-client-cert.p12
-ml.aai.KEYSTORE_PASSWORD=
-ml.aai.AUTH_USER=ModelLoader
-ml.aai.AUTH_PASSWORD=
# Disable ASDC polling & enable REST interface
ml.distribution.ASDC_CONNECTION_DISABLE=true
ml.debug.INGEST_SIMULATOR=enabled
-
-# Model Loader Client Configuration for the A&AI REST interface
-ml.aai.BASE_URL=https://localhost:8443
-ml.aai.MODEL_URL=/aai/v*/service-design-and-creation/models/model/
-ml.aai.NAMED_QUERY_URL=/aai/v*/service-design-and-creation/named-queries/named-query/
-ml.aai.VNF_IMAGE_URL=/aai/v*/service-design-and-creation/vnf-images
-ml.aai.KEYSTORE_FILE=aai-client-cert.p12
-ml.aai.KEYSTORE_PASSWORD=
# Disable ASDC polling & enable REST interface
ml.distribution.ASDC_CONNECTION_DISABLE=true
ml.debug.INGEST_SIMULATOR=enabled
-
-# Model Loader Client Configuration for the A&AI REST interface
-ml.aai.BASE_URL=https://localhost:8443
-ml.aai.MODEL_URL=/aai/v*/service-design-and-creation/models/model/
-ml.aai.NAMED_QUERY_URL=/aai/v*/service-design-and-creation/named-queries/named-query/
-ml.aai.VNF_IMAGE_URL=/aai/v*/service-design-and-creation/vnf-images
-ml.aai.KEYSTORE_FILE=aai-client-cert.p12
-ml.aai.KEYSTORE_PASSWORD=
-ml.aai.AUTH_USER=ModelLoader
-ml.aai.AUTH_PASSWORD=
-
-# Model Loader Client Configuration for the Babel Service
-ml.babel.BASE_URL=
-ml.babel.GENERATE_ARTIFACTS_URL=/services/babel-service/v1/app/generateArtifacts
-ml.babel.KEYSTORE_FILE=aai-client-cert.p12
-ml.babel.KEYSTORE_PASSWORD=
ml.distribution.POLLING_TIMEOUT=20
ml.distribution.USER=ci
ml.distribution.ARTIFACT_TYPES=MODEL_QUERY_SPEC,TOSCA_CSAR
-
-# Model Loader Client Configuration for the A&AI REST interface
-ml.aai.BASE_URL=https://localhost:8443
-ml.aai.MODEL_URL=/aai/v*/service-design-and-creation/models/model/
-ml.aai.NAMED_QUERY_URL=/aai/v*/service-design-and-creation/named-queries/named-query/
-ml.aai.VNF_IMAGE_URL=/aai/v*/service-design-and-creation/vnf-images
-ml.aai.KEYSTORE_FILE=aai-client-cert.p12
-ml.aai.KEYSTORE_PASSWORD=
-ml.aai.AUTH_USER=ModelLoader
-ml.aai.AUTH_PASSWORD=
-
-# Model Loader Client Configuration for the Babel Service
-ml.babel.BASE_URL=
-ml.babel.GENERATE_ARTIFACTS_URL=
-ml.babel.KEYSTORE_FILE=
-ml.babel.KEYSTORE_PASSWORD=
major=1
minor=14
-patch=2
+patch=3
base_version=${major}.${minor}.${patch}