|
| 1 | +package com.axway.apim.api.export.impl; |
| 2 | + |
| 3 | +import java.util.ArrayList; |
| 4 | +import java.util.Iterator; |
| 5 | +import java.util.List; |
| 6 | + |
| 7 | +import com.axway.apim.adapter.APIManagerAdapter; |
| 8 | +import com.axway.apim.adapter.APIManagerAdapter.CUSTOM_PROP_TYPE; |
| 9 | +import com.axway.apim.adapter.apis.APIFilter; |
| 10 | +import com.axway.apim.adapter.apis.APIFilter.Builder.APIType; |
| 11 | +import com.axway.apim.api.API; |
| 12 | +import com.axway.apim.api.export.lib.APIChangeParams; |
| 13 | +import com.axway.apim.api.export.lib.APIExportParams; |
| 14 | +import com.axway.apim.api.model.ServiceProfile; |
| 15 | +import com.axway.apim.api.state.APIChangeState; |
| 16 | +import com.axway.apim.apiimport.APIImportManager; |
| 17 | +import com.axway.apim.lib.errorHandling.AppException; |
| 18 | +import com.axway.apim.lib.errorHandling.ErrorCode; |
| 19 | +import com.axway.apim.lib.utils.Utils; |
| 20 | + |
| 21 | +public class APIChangeHandler extends APIResultHandler { |
| 22 | + |
| 23 | + APIChangeParams changeParams; |
| 24 | + |
| 25 | + public APIChangeHandler(APIExportParams params) { |
| 26 | + super(params); |
| 27 | + this.changeParams = (APIChangeParams)params; |
| 28 | + } |
| 29 | + |
| 30 | + @Override |
| 31 | + public void execute(List<API> apis) throws AppException { |
| 32 | + APIManagerAdapter adapter = APIManagerAdapter.getInstance(); |
| 33 | + List<APIChangeState> apisToChange = new ArrayList<APIChangeState>(); |
| 34 | + LOG.info(apis.size() + " selected to change."); |
| 35 | + for(API api : apis) { |
| 36 | + try { |
| 37 | + if(changeParams.getNewBackend()!=null) { |
| 38 | + api = changeBackendBasePath(api, changeParams.getNewBackend(), changeParams.getOldBackend()); |
| 39 | + } |
| 40 | + // Reload the actual API again, to get a clone |
| 41 | + API actualAPI = adapter.apiAdapter.getAPI(new APIFilter.Builder(APIType.ACTUAL_API).hasId(api.getId()).build(), false); |
| 42 | + APIChangeState changeState = new APIChangeState(actualAPI, api); |
| 43 | + if(!changeState.hasAnyChanges()) { |
| 44 | + LOG.warn("No changes for API: '"+api.getName()+"'"); |
| 45 | + continue; |
| 46 | + } |
| 47 | + if(changeState.isBreaking() && !params.isForce()) { |
| 48 | + LOG.error("Changing API: '"+api.getName()+"' is a potentially breaking change which can't be applied without enforcing it! Try option: -force"); |
| 49 | + continue; |
| 50 | + } |
| 51 | + LOG.info("Planned changes for API: '" + api.getName() + "': " + changeState.getAllChanges()); |
| 52 | + apisToChange.add(changeState); |
| 53 | + } catch(Exception e) { |
| 54 | + LOG.error("Error preparing required changes for API: " + api.getName(), e); |
| 55 | + } |
| 56 | + } |
| 57 | + if(apisToChange.size()==0) { |
| 58 | + System.out.println("No changes required for the selected APIs."); |
| 59 | + return; |
| 60 | + } |
| 61 | + System.out.println("Okay, going to change: " + apisToChange.size() + " API(s)"); |
| 62 | + if(Utils.askYesNo("Do you wish to proceed? (Y/N)")) { |
| 63 | + APIImportManager importManager = new APIImportManager(); |
| 64 | + for(APIChangeState changeState : apisToChange) { |
| 65 | + LOG.info("Apply changes for API: '" + changeState.getDesiredAPI().getName() +"'"); |
| 66 | + try { |
| 67 | + importManager.applyChanges(changeState); |
| 68 | + } catch(Exception e) { |
| 69 | + LOG.error("Error applying changes for API: " + changeState.getDesiredAPI().getName(), e); |
| 70 | + } |
| 71 | + } |
| 72 | + System.out.println("Done!"); |
| 73 | + } |
| 74 | + } |
| 75 | + |
| 76 | + @Override |
| 77 | + public APIFilter getFilter() { |
| 78 | + // We need to load the complete API, as this becomes the desired API |
| 79 | + // hence, all App, Orgs, Quotas, etc. must be taken over the new API |
| 80 | + return getBaseAPIFilterBuilder() |
| 81 | + .includeCustomProperties(APIManagerAdapter.getAllConfiguredCustomProperties(CUSTOM_PROP_TYPE.api)) |
| 82 | + .includeOriginalAPIDefinition(true) |
| 83 | + .includeClientApplications(true) |
| 84 | + .includeClientAppQuota(true) |
| 85 | + .includeClientOrganizations(true) |
| 86 | + .includeQuotas(true) |
| 87 | + .build(); |
| 88 | + } |
| 89 | + |
| 90 | + private API changeBackendBasePath(API api, String newBackendBasepath, String oldBackendBasepath) throws AppException { |
| 91 | + if(oldBackendBasepath!=null) { |
| 92 | + String actualBackend = getActualBackendBasepath(api); |
| 93 | + if(!oldBackendBasepath.equals(actualBackend)) { |
| 94 | + LOG.warn("Backend of API: " + api.getName() + " wont be changed as it has a different backend configured. Current: '" + actualBackend + "' New: '"+oldBackendBasepath+"'"); |
| 95 | + return api; |
| 96 | + } |
| 97 | + } |
| 98 | + Iterator<ServiceProfile> it = api.getServiceProfiles().values().iterator(); |
| 99 | + while(it.hasNext()) { |
| 100 | + ServiceProfile profile = it.next(); |
| 101 | + profile.setBasePath(newBackendBasepath); |
| 102 | + } |
| 103 | + return api; |
| 104 | + } |
| 105 | + |
| 106 | + private String getActualBackendBasepath(API api) throws AppException { |
| 107 | + Iterator<ServiceProfile> it = api.getServiceProfiles().values().iterator(); |
| 108 | + String lastBasepath = null; |
| 109 | + while(it.hasNext()) { |
| 110 | + ServiceProfile profile = it.next(); |
| 111 | + if(lastBasepath!=null && !lastBasepath.equals(profile.getBasePath())) { |
| 112 | + throw new AppException("API has multiple backends configured. Please export - change - import the API to change it.", ErrorCode.UNSUPPORTED_FEATURE); |
| 113 | + } |
| 114 | + lastBasepath = profile.getBasePath(); |
| 115 | + } |
| 116 | + return lastBasepath; |
| 117 | + } |
| 118 | + |
| 119 | +} |
0 commit comments