aboutsummaryrefslogtreecommitdiffstats
path: root/standardization/api-custom-header/src
diff options
context:
space:
mode:
authorluna <nil@vmware.com>2019-02-25 11:13:26 +0800
committerni lu <nil@vmware.com>2019-03-15 02:53:45 +0000
commitdc478d6c91264f483c6dfb79cf1ff80a12eb1be2 (patch)
tree5f06e63474295992d4ec7cfc026e1a763ce0352a /standardization/api-custom-header/src
parentc852448b1e6ca5e28e0b0dab26c2af3d5af3f390 (diff)
api custom header
Issue-ID: DCAEGEN2-897 Change-Id: Iaff1a8f71a0ab1be997fbea654d6032eee91009b Signed-off-by: luna <nil@vmware.com>
Diffstat (limited to 'standardization/api-custom-header/src')
-rw-r--r--standardization/api-custom-header/src/main/java/org/onap/dcaegen2/services/sdk/standardization/header/ApiVersionManagement.java141
-rw-r--r--standardization/api-custom-header/src/main/java/org/onap/dcaegen2/services/sdk/standardization/header/ApiVersionModel.java53
-rw-r--r--standardization/api-custom-header/src/main/java/org/onap/dcaegen2/services/sdk/standardization/header/CustomHeaderUtils.java222
-rw-r--r--standardization/api-custom-header/src/main/java/org/onap/dcaegen2/services/sdk/standardization/util/ObjectManagement.java53
-rw-r--r--standardization/api-custom-header/src/test/java/org/onap/dcaegen2/services/sdk/standardization/header/CustomHeaderUtilsTest.java75
-rw-r--r--standardization/api-custom-header/src/test/resources/api_version_config.json7
6 files changed, 551 insertions, 0 deletions
diff --git a/standardization/api-custom-header/src/main/java/org/onap/dcaegen2/services/sdk/standardization/header/ApiVersionManagement.java b/standardization/api-custom-header/src/main/java/org/onap/dcaegen2/services/sdk/standardization/header/ApiVersionManagement.java
new file mode 100644
index 00000000..06515dca
--- /dev/null
+++ b/standardization/api-custom-header/src/main/java/org/onap/dcaegen2/services/sdk/standardization/header/ApiVersionManagement.java
@@ -0,0 +1,141 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dcaegen2.services.sdk
+ * ================================================================================
+ * Copyright (C) 2019 vmware. 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.dcaegen2.services.sdk.standardization.header;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.onap.dcaegen2.services.sdk.standardization.util.ObjectManagement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.google.gson.Gson;
+
+public final class ApiVersionManagement {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ApiVersionManagement.class);
+ private static final Object INSTANCE = new Object();
+ private static final String API_VERSION = "apiVersion";
+
+ private static Map<String, List<ApiVersionModel>> verModelMap;
+
+ /**
+ * private constructor
+ */
+ private ApiVersionManagement() {
+
+ }
+
+ /**
+ * get api version from json string
+ *
+ * @param apiFilePath api file path
+ * @param requestedApiName current api name
+ * @return all api version for a major version
+ */
+ public static List<ApiVersionModel> getApiVersion(String apiFilePath, String requestedApiName) {
+ if (null != verModelMap) {
+ List<ApiVersionModel> apiLst = verModelMap.get(requestedApiName);
+ return ObjectManagement.isCollectionEmpty(apiLst) ? Collections.emptyList()
+ : Collections.unmodifiableList(apiLst);
+ }
+
+ synchronized (INSTANCE) {
+ if (null == verModelMap) {
+ verModelMap = new HashMap<>();
+ String apiVerJsonStr = readApiVersions(apiFilePath);
+
+ // component not pass the apiversion parameter
+ if (apiVerJsonStr.isEmpty()) {
+ return Collections.emptyList();
+ }
+
+ // read service or resource api and put in HashMap one by one.
+ convertVerToModel(parseApiVersion(apiVerJsonStr));
+ }
+ }
+
+ List<ApiVersionModel> apiLst = verModelMap.get(requestedApiName);
+ return ObjectManagement.isCollectionEmpty(apiLst) ? Collections.emptyList()
+ : Collections.unmodifiableList(verModelMap.get(requestedApiName));
+ }
+
+ /**
+ * parse api versions from api json string
+ *
+ * @param apiVerJsonStr all api versions in json format
+ * @return api versions<apikey, List<version>> in map format
+ */
+ private static Map<String, Object> parseApiVersion(String apiVerJsonStr) {
+ Map<String, Object> apiMap = new Gson().fromJson(apiVerJsonStr, Map.class);
+ if (apiMap.containsKey(API_VERSION)) {
+ return apiMap;
+ }
+
+ // there is no apiVersion filed in apiVerJsonStr or the format is wrong.
+ LOGGER.error("the struct of api version is wrong, so return the empty api map.");
+ return Collections.emptyMap();
+ }
+
+ /**
+ * convert api version into ApiVersionModel object
+ *
+ * @param apiMap Map object for all api versions
+ */
+ private static void convertVerToModel(Map<String, Object> apiMap) {
+ if (apiMap.isEmpty()) {
+ verModelMap = Collections.emptyMap();
+ return;
+ }
+
+ List<Object> currApiArray = null;
+ Map<String, Object> apiVersMap = (apiMap.get(API_VERSION) instanceof Map) ? (Map) apiMap.get(API_VERSION) : null;
+ if (null != apiVersMap) {
+ for (Map.Entry<String, Object> entry : apiVersMap.entrySet()) {
+ currApiArray = (entry.getValue() instanceof List) ? (List) entry.getValue() : null;
+ if (null != currApiArray) {
+ List<ApiVersionModel> currApiLst = new ArrayList<>();
+ currApiArray.forEach(currApi -> currApiLst.add(new ApiVersionModel(currApi.toString())));
+ verModelMap.put(entry.getKey(), currApiLst);
+ }
+ }
+ }
+ }
+
+ /**
+ * read api version from path
+ *
+ * @param filePath api versions
+ * @return api versions json string
+ */
+ private static String readApiVersions(String filePath) {
+ try {
+ return new String(Files.readAllBytes(Paths.get(filePath)));
+ } catch (IOException e) {
+ LOGGER.error("Fail to read api version file", e);
+ }
+
+ return "";
+ }
+} \ No newline at end of file
diff --git a/standardization/api-custom-header/src/main/java/org/onap/dcaegen2/services/sdk/standardization/header/ApiVersionModel.java b/standardization/api-custom-header/src/main/java/org/onap/dcaegen2/services/sdk/standardization/header/ApiVersionModel.java
new file mode 100644
index 00000000..d3c09a2b
--- /dev/null
+++ b/standardization/api-custom-header/src/main/java/org/onap/dcaegen2/services/sdk/standardization/header/ApiVersionModel.java
@@ -0,0 +1,53 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dcaegen2.services.sdk
+ * ================================================================================
+ * Copyright (C) 2019 vmware. 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.dcaegen2.services.sdk.standardization.header;
+
+public class ApiVersionModel {
+ private String majorVersion;
+ private String minorVersion;
+ private String patchVersion;
+ private String version;
+
+ public ApiVersionModel(String version) {
+ this.version = version;
+ if (null != version) {
+ String[] verArray = version.split("\\.");
+ majorVersion = verArray[0];
+ minorVersion = verArray.length > 1 ? verArray[1] : null;
+ patchVersion = verArray.length > 2 ? verArray[2] : null;
+ }
+ }
+
+ public String getMajorVersion() {
+ return majorVersion;
+ }
+
+ public String getMinorVersion() {
+ return minorVersion;
+ }
+
+ public String getPatchVersion() {
+ return patchVersion;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+} \ No newline at end of file
diff --git a/standardization/api-custom-header/src/main/java/org/onap/dcaegen2/services/sdk/standardization/header/CustomHeaderUtils.java b/standardization/api-custom-header/src/main/java/org/onap/dcaegen2/services/sdk/standardization/header/CustomHeaderUtils.java
new file mode 100644
index 00000000..ecd08314
--- /dev/null
+++ b/standardization/api-custom-header/src/main/java/org/onap/dcaegen2/services/sdk/standardization/header/CustomHeaderUtils.java
@@ -0,0 +1,222 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dcaegen2.services.sdk
+ * ================================================================================
+ * Copyright (C) 2019 vmware. 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.dcaegen2.services.sdk.standardization.header;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.jetbrains.annotations.NotNull;
+import org.onap.dcaegen2.services.sdk.standardization.util.ObjectManagement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CustomHeaderUtils {
+
+ private static final Logger logger = LoggerFactory.getLogger(CustomHeaderUtils.class);
+
+ /**
+ * more detail:
+ * https://wiki.onap.org/display/DW/ONAP+API+Common+Versioning+Strategy+%28CVS%29+Guidelines
+ */
+ private static final String API_MINOR_VERSION = "X-MinorVersion";
+ private static final String API_PATCH_VERSION = "X-PatchVersion";
+ private static final String API_LATEST_VERSION = "X-LatestVersion";
+
+ /**
+ * identify whether validate minor version successfully
+ */
+ private static final ThreadLocal<Boolean> CLIENT_MINOR_VERSION_OK = new ThreadLocal<>();
+ private String majorVersion = null;
+ private String minorVersion = null;
+ private List<ApiVersionModel> verLst = null;
+
+ /**
+ * construct
+ *
+ * @param requestMajorVer client request major version
+ * @param reqHeaderMap request headers
+ * @param apiFilePath api file path
+ * @param requestedApiName api name that is requested by client
+ *
+ */
+ public CustomHeaderUtils(@NotNull String requestMajorVer, @NotNull Map<String, String> reqHeaderMap,
+ @NotNull String apiFilePath, @NotNull String requestedApiName) {
+ // all api versions
+ if (!requestedApiName.isEmpty()) {
+ verLst = ApiVersionManagement.getApiVersion(apiFilePath, requestedApiName);
+ }
+
+ // major version that client requests
+ this.majorVersion = requestMajorVer;
+
+ // minor version that client requests
+ this.minorVersion = reqHeaderMap.get(API_MINOR_VERSION);
+
+ CLIENT_MINOR_VERSION_OK.set(Boolean.TRUE);
+ }
+
+ /**
+ * get the custom headers of response
+ *
+ * @return rspHeader custom headers of response
+ */
+ public Map<String, String> getRspCustomHeader() {
+ try {
+ return calCustomHeader();
+ } finally {
+ CLIENT_MINOR_VERSION_OK.remove();
+ }
+ }
+
+ /**
+ * calculate the custom header for response
+ *
+ * @return rspHeader custom headers of response
+ */
+ private Map<String, String> calCustomHeader() {
+ if (ObjectManagement.isCollectionEmpty(this.verLst)) {
+ logger.warn("there is no api version configured in server.");
+ return new HashMap<>();
+ }
+
+ // if client not send X-MinorVersion, return the first minor version that major version is requested
+ if (ObjectManagement.isStringEmpty(this.minorVersion)) {
+ return calHeadersNoMinorVer();
+ }
+
+ // if client send x-MinorVersion, minor vefrsion is wrong
+ if (!CLIENT_MINOR_VERSION_OK.get()) {
+ return calHeadersWithWrongMinorVer();
+ }
+
+ // client send X-MinorVersion and minor version is right
+ return calHeadersWithMinorVer();
+ }
+
+ /**
+ * calculate the custom header should be returned when client send minor version which is wrong
+ *
+ * @return rspHeader custom headers of response
+ */
+ private Map<String, String> calHeadersWithWrongMinorVer() {
+ Map<String, String> rspHeader = new HashMap<>(3);
+
+ // Latest version mean greatest version
+ rspHeader.put(API_LATEST_VERSION, this.verLst.get(verLst.size() - 1).getVersion());
+
+ ApiVersionModel currVer = null;
+ for (int index = 0; index < this.verLst.size(); index++) {
+ if (this.majorVersion.equals(this.verLst.get(index).getMajorVersion())) {
+ currVer = this.verLst.get(index);
+ } else {
+ if (null != currVer) {
+ break;
+ }
+ }
+ }
+
+ if (null == currVer) {
+ logger.warn("wrong apiVersiona are provided, major {} not foud in them", this.majorVersion);
+ } else {
+ rspHeader.put(API_MINOR_VERSION, currVer.getMinorVersion());
+ rspHeader.put(API_PATCH_VERSION, currVer.getPatchVersion());
+ }
+
+ return rspHeader;
+ }
+
+ /**
+ * calculate the custom header should be returned when client send minor version which is right
+ *
+ * @return rspHeader custom headers of response
+ */
+ private Map<String, String> calHeadersWithMinorVer() {
+ Map<String, String> rspHeader = new HashMap<>(3);
+
+ // Latest version mean greatest version
+ rspHeader.put(API_LATEST_VERSION, this.verLst.get(verLst.size() - 1).getVersion());
+
+ // set minor version
+ rspHeader.put(API_MINOR_VERSION, this.minorVersion);
+
+ // set patch version
+ ApiVersionModel currVer = null;
+ for (int index = 0; index < this.verLst.size(); index++) {
+ currVer = verLst.get(index);
+ if (this.majorVersion.equals(currVer.getMajorVersion()) && this.minorVersion.equals(currVer.getMinorVersion())) {
+ rspHeader.put(API_PATCH_VERSION, currVer.getPatchVersion());
+ break;
+ }
+ }
+
+ return rspHeader;
+ }
+
+ /**
+ * calculate the custom header should be returned when client not send minor version
+ *
+ * @return rspHeader custom headers of response
+ */
+ private Map<String, String> calHeadersNoMinorVer() {
+ Map<String, String> rspHeader = new HashMap<>(3);
+
+ // Latest version mean greatest version
+ rspHeader.put(API_LATEST_VERSION, this.verLst.get(verLst.size() - 1).getVersion());
+
+ // the first version of major version
+ ApiVersionModel currVer = null;
+ for (int index = 0; index < this.verLst.size(); index++) {
+ currVer = verLst.get(index);
+ if (this.majorVersion.equals(currVer.getMajorVersion())) {
+ rspHeader.put(API_MINOR_VERSION, currVer.getMinorVersion());
+ rspHeader.put(API_PATCH_VERSION, currVer.getPatchVersion());
+ break;
+ }
+ }
+
+ return rspHeader;
+ }
+
+ /**
+ * Check header whether it is right.
+ *
+ * @return true when validating successfully or minor version not exist
+ */
+ public boolean isOkCustomHeaders() {
+ if (ObjectManagement.isStringEmpty(this.minorVersion)) {
+ logger.warn("X-MinorVersion is empty or null");
+ return true;
+ }
+
+ ApiVersionModel currVer = null;
+
+ // verList is an order array, which is from the first version to the latest version.
+ for (int index = 0; index < this.verLst.size(); index++) {
+ currVer = verLst.get(index);
+ if (currVer.getMajorVersion().equals(this.majorVersion) && currVer.getMinorVersion().equals(this.minorVersion)) {
+ return true;
+ }
+ }
+
+ logger.error("not find major version {} and minor version {}", this.majorVersion, this.minorVersion);
+ CLIENT_MINOR_VERSION_OK.set(Boolean.FALSE);
+ return false;
+ }
+} \ No newline at end of file
diff --git a/standardization/api-custom-header/src/main/java/org/onap/dcaegen2/services/sdk/standardization/util/ObjectManagement.java b/standardization/api-custom-header/src/main/java/org/onap/dcaegen2/services/sdk/standardization/util/ObjectManagement.java
new file mode 100644
index 00000000..3f173d31
--- /dev/null
+++ b/standardization/api-custom-header/src/main/java/org/onap/dcaegen2/services/sdk/standardization/util/ObjectManagement.java
@@ -0,0 +1,53 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dcaegen2.services.sdk
+ * ================================================================================
+ * Copyright (C) 2019 vmware. 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.dcaegen2.services.sdk.standardization.util;
+
+
+import java.util.Collection;
+
+public final class ObjectManagement {
+
+ /**
+ * constructor that not permit to new object
+ */
+ private ObjectManagement() {
+
+ }
+
+ /**
+ * check string object if it is empty
+ *
+ * @param str string object
+ * @return true when str is null or empty
+ */
+ public static boolean isStringEmpty(String str) {
+ return null == str || str.isEmpty();
+ }
+
+ /**
+ * check collection object if it is empty
+ *
+ * @param c collection object
+ * @return true when c is null or empty
+ */
+ public static boolean isCollectionEmpty(Collection<?> c) {
+ return null == c || c.isEmpty();
+ }
+} \ No newline at end of file
diff --git a/standardization/api-custom-header/src/test/java/org/onap/dcaegen2/services/sdk/standardization/header/CustomHeaderUtilsTest.java b/standardization/api-custom-header/src/test/java/org/onap/dcaegen2/services/sdk/standardization/header/CustomHeaderUtilsTest.java
new file mode 100644
index 00000000..73fcec1a
--- /dev/null
+++ b/standardization/api-custom-header/src/test/java/org/onap/dcaegen2/services/sdk/standardization/header/CustomHeaderUtilsTest.java
@@ -0,0 +1,75 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.dcaegen2.services.sdk
+ * ================================================================================
+ * Copyright (C) 2019 vmware. 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.dcaegen2.services.sdk.standardization.header;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+class CustomHeaderUtilsTest {
+ private String filePath = getClass().getClassLoader().getResource("api_version_config.json").getPath();
+
+ /**
+ * not send minor version when client requests
+ */
+ @Test
+ void testRequestNoMinorVer() {
+ CustomHeaderUtils util = getHeaderUtil(null);
+ util.isOkCustomHeaders();
+
+ Map<String, String> rspHeaders = util.getRspCustomHeader();
+ Assertions.assertTrue("3".equals(rspHeaders.get("X-MinorVersion")));
+ }
+
+ /**
+ * minor version not exist which client request
+ */
+ @Test
+ void testRequestWithWrongMinorVer() {
+ CustomHeaderUtils util = getHeaderUtil("2");
+
+ // check request header
+ util.isOkCustomHeaders();
+
+ Assertions.assertFalse(util.isOkCustomHeaders());
+
+ Map<String, String> rspHeaders = util.getRspCustomHeader();
+ Assertions.assertTrue("4".equals(rspHeaders.get("X-MinorVersion")));
+ }
+
+ /**
+ * minor version exists which client request
+ */
+ @Test
+ void testRequestWithMinorVerOk() {
+ CustomHeaderUtils util = getHeaderUtil("3");
+ Assertions.assertFalse(!util.isOkCustomHeaders());
+
+ Map<String, String> rspHeaders = util.getRspCustomHeader();
+ Assertions.assertTrue("3".equals(rspHeaders.get("X-MinorVersion")));
+ }
+
+ private CustomHeaderUtils getHeaderUtil(String minorVer) {
+ Map<String, String> reqHeaderMap = new HashMap<String, String>();
+ reqHeaderMap.put("X-MinorVersion", minorVer);
+ return new CustomHeaderUtils("5", reqHeaderMap, filePath, "eventListener");
+ }
+} \ No newline at end of file
diff --git a/standardization/api-custom-header/src/test/resources/api_version_config.json b/standardization/api-custom-header/src/test/resources/api_version_config.json
new file mode 100644
index 00000000..81468ac4
--- /dev/null
+++ b/standardization/api-custom-header/src/test/resources/api_version_config.json
@@ -0,0 +1,7 @@
+{
+ "apiVersion":
+ {
+ "eventListener": ["4.7.2","5.3.2","5.4.1","7.0.1"],
+ "xxxxxx": ["1.0.2","1.1.2","2.0.1"]
+ }
+} \ No newline at end of file