diff options
author | luna <nil@vmware.com> | 2019-02-25 11:13:26 +0800 |
---|---|---|
committer | ni lu <nil@vmware.com> | 2019-03-15 02:53:45 +0000 |
commit | dc478d6c91264f483c6dfb79cf1ff80a12eb1be2 (patch) | |
tree | 5f06e63474295992d4ec7cfc026e1a763ce0352a /standardization/api-custom-header/src/main/java | |
parent | c852448b1e6ca5e28e0b0dab26c2af3d5af3f390 (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/main/java')
4 files changed, 469 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 |