diff --git a/common-controller/internal/operator/controllers/cp/application_controller.go b/common-controller/internal/operator/controllers/cp/application_controller.go index 3a6756df8..b5c49d730 100644 --- a/common-controller/internal/operator/controllers/cp/application_controller.go +++ b/common-controller/internal/operator/controllers/cp/application_controller.go @@ -101,7 +101,7 @@ func sendAppUpdates(applicationList *cpv1alpha2.ApplicationList) { server.AddApplicationKeyMapping(appKeyMappingList) } -func marshalApplicationList(applicationList []cpv1alpha2.Application) *server.ApplicationList { +func marshalApplicationList(applicationList []cpv1alpha2.Application) server.ApplicationList { applications := []server.Application{} for _, appInternal := range applicationList { app := server.Application{ @@ -113,7 +113,7 @@ func marshalApplicationList(applicationList []cpv1alpha2.Application) *server.Ap } applications = append(applications, app) } - return &server.ApplicationList{ + return server.ApplicationList{ List: applications, } } diff --git a/common-controller/internal/operator/controllers/cp/subscription_controller.go b/common-controller/internal/operator/controllers/cp/subscription_controller.go index c7714ef2a..13aaeaf8f 100644 --- a/common-controller/internal/operator/controllers/cp/subscription_controller.go +++ b/common-controller/internal/operator/controllers/cp/subscription_controller.go @@ -100,7 +100,7 @@ func sendSubUpdates(subscriptionsList *cpv1alpha2.SubscriptionList) { server.AddSubscription(subList) } -func marshalSubscriptionList(subscriptionList []cpv1alpha2.Subscription) *server.SubscriptionList { +func marshalSubscriptionList(subscriptionList []cpv1alpha2.Subscription) server.SubscriptionList { subscriptions := []server.Subscription{} for _, subInternal := range subscriptionList { subscribedAPI := &server.SubscribedAPI{} @@ -116,5 +116,5 @@ func marshalSubscriptionList(subscriptionList []cpv1alpha2.Subscription) *server sub.SubscribedAPI = subscribedAPI subscriptions = append(subscriptions, sub) } - return &server.SubscriptionList{List: subscriptions} + return server.SubscriptionList{List: subscriptions} } diff --git a/common-controller/internal/server/server.go b/common-controller/internal/server/server.go index f453d6732..c48081102 100644 --- a/common-controller/internal/server/server.go +++ b/common-controller/internal/server/server.go @@ -8,37 +8,25 @@ import ( "github.com/wso2/apk/common-controller/internal/config" ) -var applicationList *ApplicationList -var subscriptionList *SubscriptionList -var applicationMappingList *ApplicationMappingList -var applicationKeyMappingList *ApplicationKeyMappingList +var applicationList = ApplicationList{List: []Application{}} +var subscriptionList = SubscriptionList{List: []Subscription{}} +var applicationMappingList = ApplicationMappingList{List: []ApplicationMapping{}} +var applicationKeyMappingList = ApplicationKeyMappingList{List: []ApplicationKeyMapping{}} // StartInternalServer starts the internal server func StartInternalServer() { r := gin.Default() r.GET("/applications", func(c *gin.Context) { - if applicationList == nil { - c.JSON(http.StatusOK, ApplicationList{List: make([]Application, 0)}) - } c.JSON(http.StatusOK, applicationList) }) r.GET("/subscriptions", func(c *gin.Context) { - if subscriptionList == nil { - c.JSON(http.StatusOK, SubscriptionList{List: make([]Subscription, 0)}) - } c.JSON(http.StatusOK, subscriptionList) }) r.GET("/applicationmappings", func(c *gin.Context) { - if applicationMappingList == nil { - c.JSON(http.StatusOK, ApplicationMappingList{List: make([]ApplicationMapping, 0)}) - } c.JSON(http.StatusOK, applicationMappingList) }) r.GET("/applicationkeymappings", func(c *gin.Context) { - if applicationKeyMappingList == nil { - c.JSON(http.StatusOK, ApplicationKeyMappingList{List: make([]ApplicationKeyMapping, 0)}) - } c.JSON(http.StatusOK, applicationKeyMappingList) }) gin.SetMode(gin.ReleaseMode) @@ -50,21 +38,21 @@ func StartInternalServer() { } // AddApplication adds an application to the application list -func AddApplication(appList *ApplicationList) { +func AddApplication(appList ApplicationList) { applicationList = appList } // AddSubscription adds a subscription to the subscription list -func AddSubscription(subList *SubscriptionList) { +func AddSubscription(subList SubscriptionList) { subscriptionList = subList } // AddApplicationMapping adds an application mapping to the application mapping list func AddApplicationMapping(appMappingList ApplicationMappingList) { - applicationMappingList = &appMappingList + applicationMappingList = appMappingList } // AddApplicationKeyMapping adds an application key mapping to the application key mapping list func AddApplicationKeyMapping(appKeyMappingList ApplicationKeyMappingList) { - applicationKeyMappingList = &appKeyMappingList + applicationKeyMappingList = appKeyMappingList } diff --git a/gateway/enforcer/org.wso2.apk.enforcer/build.gradle b/gateway/enforcer/org.wso2.apk.enforcer/build.gradle index 36e56a3e3..e2eb59909 100644 --- a/gateway/enforcer/org.wso2.apk.enforcer/build.gradle +++ b/gateway/enforcer/org.wso2.apk.enforcer/build.gradle @@ -81,6 +81,13 @@ dependencies { implementation libs.reactor.netty.http implementation libs.protobuf.java implementation libs.jedis + implementation libs.feign.httpclient + implementation libs.gson + implementation libs.ua.parser + implementation libs.commons.lang3 + implementation libs.openfeign.feign.gson + implementation libs.openfeign.feign.slf4j + test { implementation libs.junit implementation libs.mockito.inline diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/config/ConfigHolder.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/config/ConfigHolder.java index c5e6db70a..ace948920 100644 --- a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/config/ConfigHolder.java +++ b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/config/ConfigHolder.java @@ -66,9 +66,11 @@ import java.io.IOException; import java.lang.reflect.Field; +import java.security.Key; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; +import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPublicKey; @@ -91,6 +93,8 @@ public class ConfigHolder { private static ConfigHolder configHolder; private final EnvVarConfig envVarConfig = EnvVarConfig.getInstance(); EnforcerConfig config = new EnforcerConfig(); + + private KeyStore keyStore = null; private KeyStore trustStore = null; private KeyStore trustStoreForJWT = null; private KeyStore opaKeyStore = null; @@ -101,6 +105,22 @@ private ConfigHolder() { loadTrustStore(); loadOpaClientKeyStore(); + loadKeyStore(); + } + + private void loadKeyStore() { + + try { + Certificate cert = + TLSUtils.getCertificateFromFile(getEnvVarConfig().getEnforcerPublicKeyPath()); + Key key = JWTUtils.getPrivateKey(getEnvVarConfig().getEnforcerPrivateKeyPath()); + keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); + keyStore.load(null, null); + keyStore.setKeyEntry("client-keys", key, null, new Certificate[]{cert}); + } catch (EnforcerException | CertificateException | IOException | KeyStoreException | + NoSuchAlgorithmException e) { + logger.error("Error occurred while configuring KeyStore", e); + } } public static ConfigHolder getInstance() { @@ -307,6 +327,16 @@ private void populateJWTGeneratorConfigurations(JWTGenerator jwtGenerator) { populateBackendJWKSConfiguration(jwtGenerator); } + public KeyStore getKeyStore() { + + return keyStore; + } + + public void setKeyStore(KeyStore keyStore) { + + this.keyStore = keyStore; + } + private void populateBackendJWKSConfiguration(JWTGenerator jwtGenerator) { BackendJWKSDto backendJWKSDto = new BackendJWKSDto(); diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/config/EnvVarConfig.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/config/EnvVarConfig.java index 1a3ac0877..1d4367285 100644 --- a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/config/EnvVarConfig.java +++ b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/config/EnvVarConfig.java @@ -37,6 +37,8 @@ public class EnvVarConfig { private static final String ADAPTER_XDS_PORT = "ADAPTER_XDS_PORT"; private static final String COMMON_CONTROLLER_HOST = "COMMON_CONTROLLER_HOST"; private static final String COMMON_CONTROLLER_XDS_PORT = "COMMON_CONTROLLER_XDS_PORT"; + private static final String COMMON_CONTROLLER_REST_PORT = "COMMON_CONTROLLER_REST_PORT"; + private static final String ENFORCER_LABEL = "ENFORCER_LABEL"; private static final String ENFORCER_REGION_ID = "ENFORCER_REGION"; public static final String XDS_MAX_MSG_SIZE = "XDS_MAX_MSG_SIZE"; @@ -67,6 +69,7 @@ public class EnvVarConfig { private static final String DEFAULT_ADAPTER_XDS_PORT = "18000"; private static final String DEFAULT_COMMON_CONTROLLER_HOST = "common-controller"; private static final String DEFAULT_COMMON_CONTROLLER_XDS_PORT = "18002"; + private static final String DEFAULT_COMMON_CONTROLLER_REST_PORT = "18003"; private static final String DEFAULT_ENFORCER_LABEL = "enforcer"; public static final String DEFAULT_XDS_MAX_MSG_SIZE = "4194304"; public static final String DEFAULT_XDS_MAX_RETRIES = Integer.toString(Constants.MAX_XDS_RETRIES); @@ -94,6 +97,7 @@ public class EnvVarConfig { private final String enforcerLabel; private final String adapterXdsPort; private final String commonControllerXdsPort; + private final String commonControllerRestPort; private final String adapterHostname; private final String commonControllerHostname; // TODO: (VirajSalaka) Enforcer ID should be picked from router once envoy 1.18.0 is released and microgateway @@ -136,6 +140,8 @@ private EnvVarConfig() { DEFAULT_COMMON_CONTROLLER_HOST_NAME); commonControllerXdsPort = retrieveEnvVarOrDefault(COMMON_CONTROLLER_XDS_PORT, DEFAULT_COMMON_CONTROLLER_XDS_PORT); + commonControllerRestPort = retrieveEnvVarOrDefault(COMMON_CONTROLLER_REST_PORT, + DEFAULT_COMMON_CONTROLLER_REST_PORT); xdsMaxMsgSize = retrieveEnvVarOrDefault(XDS_MAX_MSG_SIZE, DEFAULT_XDS_MAX_MSG_SIZE); enforcerRegionId = retrieveEnvVarOrDefault(ENFORCER_REGION_ID, DEFAULT_ENFORCER_REGION_ID); xdsMaxRetries = retrieveEnvVarOrDefault(XDS_MAX_RETRIES, DEFAULT_XDS_MAX_RETRIES); @@ -308,4 +314,10 @@ public String getRevokedTokensRedisChannel() { public int getRevokedTokenCleanupInterval() { return revokedTokenCleanupInterval; } + + public String getCommonControllerRestPort() { + + return commonControllerRestPort; + } } + diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/ApplicationDiscoveryClient.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/ApplicationDiscoveryClient.java deleted file mode 100644 index c119742ca..000000000 --- a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/ApplicationDiscoveryClient.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2021, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 LLC. licenses this file to you 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. - */ - -package org.wso2.apk.enforcer.discovery; - -import com.google.protobuf.Any; -import com.google.rpc.Status; -import io.envoyproxy.envoy.config.core.v3.Node; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryRequest; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryResponse; -import io.grpc.ConnectivityState; -import io.grpc.ManagedChannel; -import io.grpc.stub.StreamObserver; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.wso2.apk.enforcer.discovery.service.subscription.ApplicationDiscoveryServiceGrpc; -import org.wso2.apk.enforcer.discovery.subscription.Application; -import org.wso2.apk.enforcer.discovery.subscription.ApplicationList; -import org.wso2.apk.enforcer.config.ConfigHolder; -import org.wso2.apk.enforcer.constants.AdapterConstants; -import org.wso2.apk.enforcer.constants.Constants; -import org.wso2.apk.enforcer.discovery.common.XDSCommonUtils; -import org.wso2.apk.enforcer.discovery.scheduler.XdsSchedulerManager; -import org.wso2.apk.enforcer.subscription.SubscriptionDataStoreImpl; -import org.wso2.apk.enforcer.util.GRPCUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -/** - * Client to communicate with Application discovery service at the common-controller. - */ -public class ApplicationDiscoveryClient implements Runnable { - private static final Logger logger = LogManager.getLogger(ApplicationDiscoveryClient.class); - private static ApplicationDiscoveryClient instance; - private ManagedChannel channel; - private ApplicationDiscoveryServiceGrpc.ApplicationDiscoveryServiceStub stub; - private StreamObserver reqObserver; - private final SubscriptionDataStoreImpl subscriptionDataStore; - private final String host; - private final String hostname; - private final int port; - - /** - * This is a reference to the latest received response from the ADS. - *

- * Usage: When ack/nack a DiscoveryResponse this value is used to identify the latest received DiscoveryResponse - * which may not have been acked/nacked so far. - *

- */ - - private DiscoveryResponse latestReceived; - /** - * This is a reference to the latest acked response from the ADS. - *

- * Usage: When nack a DiscoveryResponse this value is used to find the latest successfully processed - * DiscoveryResponse. Information sent in the nack request will contain information about this response value. - *

- */ - private DiscoveryResponse latestACKed; - - /** - * Node struct for the discovery client - */ - private final Node node; - - private ApplicationDiscoveryClient(String host, String hostname, int port) { - this.host = host; - this.hostname = hostname; - this.port = port; - this.subscriptionDataStore = SubscriptionDataStoreImpl.getInstance(); - initConnection(); - this.node = XDSCommonUtils.generateXDSNode(AdapterConstants.COMMON_ENFORCER_LABEL); - this.latestACKed = DiscoveryResponse.getDefaultInstance(); - } - - private void initConnection() { - if (GRPCUtils.isReInitRequired(channel)) { - if (channel != null && !channel.isShutdown()) { - channel.shutdownNow(); - do { - try { - channel.awaitTermination(100, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - logger.error("Application discovery channel shutdown wait was interrupted", e); - } - } while (!channel.isShutdown()); - } - this.channel = GRPCUtils.createSecuredChannel(logger, host, port, hostname); - this.stub = ApplicationDiscoveryServiceGrpc.newStub(channel); - } else if (channel.getState(true) == ConnectivityState.READY) { - XdsSchedulerManager.getInstance().stopApplicationDiscoveryScheduling(); - } - } - - public static ApplicationDiscoveryClient getInstance() { - if (instance == null) { - String sdsHost = ConfigHolder.getInstance().getEnvVarConfig().getCommonControllerHost(); - String sdsHostname = ConfigHolder.getInstance().getEnvVarConfig().getCommonControllerHostname(); - int sdsPort = Integer.parseInt(ConfigHolder.getInstance().getEnvVarConfig().getCommonControllerXdsPort()); - instance = new ApplicationDiscoveryClient(sdsHost, sdsHostname, sdsPort); - } - return instance; - } - - public void run() { - initConnection(); - watchApplications(); - } - - public void watchApplications() { - // TODO: (Praminda) implement a deadline with retries - reqObserver = stub.streamApplications(new StreamObserver() { - @Override - public void onNext(DiscoveryResponse response) { - logger.info("Application creation event received with version : " + response.getVersionInfo()); - logger.debug("Received Application discovery response " + response); - XdsSchedulerManager.getInstance().stopApplicationDiscoveryScheduling(); - latestReceived = response; - try { - List applicationList = new ArrayList<>(); - for (Any res : response.getResourcesList()) { - applicationList.addAll(res.unpack(ApplicationList.class).getListList()); - } - subscriptionDataStore.addApplications(applicationList); - logger.info("Number of applications received : " + applicationList.size()); - ack(); - } catch (Exception e) { - // catching generic error here to wrap any grpc communication errors in the runtime - onError(e); - } - } - - @Override - public void onError(Throwable throwable) { - logger.error("Error occurred during Application discovery", throwable); - XdsSchedulerManager.getInstance().startApplicationDiscoveryScheduling(); - nack(throwable); - } - - @Override - public void onCompleted() { - logger.info("Completed receiving Application data"); - } - }); - - try { - DiscoveryRequest req = DiscoveryRequest.newBuilder() - .setNode(node) - .setVersionInfo(latestACKed.getVersionInfo()) - .setTypeUrl(Constants.APPLICATION_LIST_TYPE_URL).build(); - reqObserver.onNext(req); - logger.debug("Sent Discovery request for type url: " + Constants.APPLICATION_LIST_TYPE_URL); - - } catch (Exception e) { - logger.error("Unexpected error occurred in Application discovery service", e); - reqObserver.onError(e); - } - } - - /** - * Send acknowledgement of successfully processed DiscoveryResponse from the xDS server. This is part of the xDS - * communication protocol. - */ - private void ack() { - DiscoveryRequest req = DiscoveryRequest.newBuilder() - .setNode(node) - .setVersionInfo(latestReceived.getVersionInfo()) - .setResponseNonce(latestReceived.getNonce()) - .setTypeUrl(Constants.APPLICATION_LIST_TYPE_URL).build(); - reqObserver.onNext(req); - latestACKed = latestReceived; - } - - private void nack(Throwable e) { - if (latestReceived == null) { - return; - } - DiscoveryRequest req = DiscoveryRequest.newBuilder() - .setNode(node) - .setVersionInfo(latestACKed.getVersionInfo()) - .setResponseNonce(latestReceived.getNonce()) - .setTypeUrl(Constants.APPLICATION_LIST_TYPE_URL) - .setErrorDetail(Status.newBuilder().setMessage(e.getMessage())) - .build(); - reqObserver.onNext(req); - } -} diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/ApplicationKeyMappingDiscoveryClient.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/ApplicationKeyMappingDiscoveryClient.java deleted file mode 100644 index b7215f337..000000000 --- a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/ApplicationKeyMappingDiscoveryClient.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2021, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 LLC. licenses this file to you 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. - */ - -package org.wso2.apk.enforcer.discovery; - -import com.google.protobuf.Any; -import com.google.rpc.Status; -import io.envoyproxy.envoy.config.core.v3.Node; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryRequest; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryResponse; -import io.grpc.ConnectivityState; -import io.grpc.ManagedChannel; -import io.grpc.stub.StreamObserver; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.wso2.apk.enforcer.discovery.service.subscription.ApplicationKeyMappingDiscoveryServiceGrpc; -import org.wso2.apk.enforcer.discovery.subscription.ApplicationKeyMapping; -import org.wso2.apk.enforcer.discovery.subscription.ApplicationKeyMappingList; -import org.wso2.apk.enforcer.config.ConfigHolder; -import org.wso2.apk.enforcer.constants.AdapterConstants; -import org.wso2.apk.enforcer.constants.Constants; -import org.wso2.apk.enforcer.discovery.common.XDSCommonUtils; -import org.wso2.apk.enforcer.discovery.scheduler.XdsSchedulerManager; -import org.wso2.apk.enforcer.subscription.SubscriptionDataStoreImpl; -import org.wso2.apk.enforcer.util.GRPCUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -/** - * Client to communicate with Application Key Mapping discovery service at the common-controller. - */ -public class ApplicationKeyMappingDiscoveryClient implements Runnable { - private static final Logger logger = LogManager.getLogger(ApplicationKeyMappingDiscoveryClient.class); - private static ApplicationKeyMappingDiscoveryClient instance; - private ManagedChannel channel; - private ApplicationKeyMappingDiscoveryServiceGrpc.ApplicationKeyMappingDiscoveryServiceStub stub; - private StreamObserver reqObserver; - private final SubscriptionDataStoreImpl subscriptionDataStore; - private final String host; - private final String hostname; - private final int port; - - /** - * This is a reference to the latest received response from the ADS. - *

- * Usage: When ack/nack a DiscoveryResponse this value is used to identify the latest received DiscoveryResponse - * which may not have been acked/nacked so far. - *

- */ - - private DiscoveryResponse latestReceived; - /** - * This is a reference to the latest acked response from the ADS. - *

- * Usage: When nack a DiscoveryResponse this value is used to find the latest successfully processed - * DiscoveryResponse. Information sent in the nack request will contain information about this response value. - *

- */ - private DiscoveryResponse latestACKed; - - /** - * Node struct for the discovery client - */ - private final Node node; - - private ApplicationKeyMappingDiscoveryClient(String host, String hostname, int port) { - this.host = host; - this.hostname = hostname; - this.port = port; - this.subscriptionDataStore = SubscriptionDataStoreImpl.getInstance(); - initConnection(); - this.node = XDSCommonUtils.generateXDSNode(AdapterConstants.COMMON_ENFORCER_LABEL); - this.latestACKed = DiscoveryResponse.getDefaultInstance(); - } - - private void initConnection() { - if (GRPCUtils.isReInitRequired(channel)) { - if (channel != null && !channel.isShutdown()) { - channel.shutdownNow(); - do { - try { - channel.awaitTermination(100, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - logger.error("Application key mapping discovery channel shutdown wait was interrupted", e); - } - } while (!channel.isShutdown()); - } - this.channel = GRPCUtils.createSecuredChannel(logger, host, port, hostname); - this.stub = ApplicationKeyMappingDiscoveryServiceGrpc.newStub(channel); - } else if (channel.getState(true) == ConnectivityState.READY) { - XdsSchedulerManager.getInstance().stopApplicationKeyMappingDiscoveryScheduling(); - } - } - - public static ApplicationKeyMappingDiscoveryClient getInstance() { - if (instance == null) { - String sdsHost = ConfigHolder.getInstance().getEnvVarConfig().getCommonControllerHost(); - String sdsHostname = ConfigHolder.getInstance().getEnvVarConfig().getCommonControllerHostname(); - int sdsPort = Integer.parseInt(ConfigHolder.getInstance().getEnvVarConfig().getCommonControllerXdsPort()); - instance = new ApplicationKeyMappingDiscoveryClient(sdsHost, sdsHostname, sdsPort); - } - return instance; - } - - public void run() { - initConnection(); - watchApplicationKeyMappings(); - } - - public void watchApplicationKeyMappings() { - // TODO: (Praminda) implement a deadline with retries - reqObserver = stub.streamApplicationKeyMappings(new StreamObserver() { - @Override - public void onNext(DiscoveryResponse response) { - logger.info("Application key generation event received with version : " + response.getVersionInfo()); - logger.debug("Received Application Key Mapping discovery response " + response); - XdsSchedulerManager.getInstance().stopApplicationKeyMappingDiscoveryScheduling(); - latestReceived = response; - try { - List applicationKeyMappingLis = new ArrayList<>(); - for (Any res : response.getResourcesList()) { - applicationKeyMappingLis.addAll(res.unpack(ApplicationKeyMappingList.class).getListList()); - } - subscriptionDataStore.addApplicationKeyMappings(applicationKeyMappingLis); - logger.info("Number of application key mappings received : " + applicationKeyMappingLis.size()); - ack(); - } catch (Exception e) { - // catching generic error here to wrap any grpc communication errors in the runtime - onError(e); - } - } - - @Override - public void onError(Throwable throwable) { - logger.error("Error occurred during Application Key Mappings discovery", throwable); - XdsSchedulerManager.getInstance().startApplicationKeyMappingDiscoveryScheduling(); - nack(throwable); - } - - @Override - public void onCompleted() { - logger.info("Completed receiving Application Key Mapping data"); - } - }); - - try { - DiscoveryRequest req = DiscoveryRequest.newBuilder() - .setNode(node) - .setVersionInfo(latestACKed.getVersionInfo()) - .setTypeUrl(Constants.APPLICATION_KEY_MAPPING_LIST_TYPE_URL).build(); - reqObserver.onNext(req); - logger.debug("Sent Discovery request for type url: " + Constants.APPLICATION_KEY_MAPPING_LIST_TYPE_URL); - - } catch (Exception e) { - logger.error("Unexpected error occurred in Application Key Mapping discovery service", e); - reqObserver.onError(e); - } - } - - /** - * Send acknowledgement of successfully processed DiscoveryResponse from the xDS server. This is part of the xDS - * communication protocol. - */ - private void ack() { - DiscoveryRequest req = DiscoveryRequest.newBuilder() - .setNode(node) - .setVersionInfo(latestReceived.getVersionInfo()) - .setResponseNonce(latestReceived.getNonce()) - .setTypeUrl(Constants.APPLICATION_KEY_MAPPING_LIST_TYPE_URL).build(); - reqObserver.onNext(req); - latestACKed = latestReceived; - } - - private void nack(Throwable e) { - if (latestReceived == null) { - return; - } - DiscoveryRequest req = DiscoveryRequest.newBuilder() - .setNode(node) - .setVersionInfo(latestACKed.getVersionInfo()) - .setResponseNonce(latestReceived.getNonce()) - .setTypeUrl(Constants.APPLICATION_KEY_MAPPING_LIST_TYPE_URL) - .setErrorDetail(Status.newBuilder().setMessage(e.getMessage())) - .build(); - reqObserver.onNext(req); - } -} diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/ApplicationMappingDiscoveryClient.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/ApplicationMappingDiscoveryClient.java deleted file mode 100644 index 18df15e92..000000000 --- a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/ApplicationMappingDiscoveryClient.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 LLC. licenses this file to you 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. - */ - -package org.wso2.apk.enforcer.discovery; - -import com.google.protobuf.Any; -import com.google.rpc.Status; -import io.envoyproxy.envoy.config.core.v3.Node; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryRequest; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryResponse; -import io.grpc.ConnectivityState; -import io.grpc.ManagedChannel; -import io.grpc.stub.StreamObserver; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.wso2.apk.enforcer.discovery.service.subscription.ApplicationMappingDiscoveryServiceGrpc; -import org.wso2.apk.enforcer.discovery.subscription.ApplicationMapping; -import org.wso2.apk.enforcer.discovery.subscription.ApplicationMappingList; -import org.wso2.apk.enforcer.config.ConfigHolder; -import org.wso2.apk.enforcer.constants.AdapterConstants; -import org.wso2.apk.enforcer.constants.Constants; -import org.wso2.apk.enforcer.discovery.common.XDSCommonUtils; -import org.wso2.apk.enforcer.discovery.scheduler.XdsSchedulerManager; -import org.wso2.apk.enforcer.subscription.SubscriptionDataStoreImpl; -import org.wso2.apk.enforcer.util.GRPCUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -/** - * Client to communicate with Application Mapping discovery service at the common-controller. - */ -public class ApplicationMappingDiscoveryClient implements Runnable { - private static final Logger logger = LogManager.getLogger(ApplicationMappingDiscoveryClient.class); - private static ApplicationMappingDiscoveryClient instance; - private ManagedChannel channel; - private ApplicationMappingDiscoveryServiceGrpc.ApplicationMappingDiscoveryServiceStub stub; - private StreamObserver reqObserver; - private final SubscriptionDataStoreImpl subscriptionDataStore; - private final String host; - private final String hostname; - private final int port; - - /** - * This is a reference to the latest received response from the ADS. - *

- * Usage: When ack/nack a DiscoveryResponse this value is used to identify the latest received DiscoveryResponse - * which may not have been acked/nacked so far. - *

- */ - private DiscoveryResponse latestReceived; - - /** - * This is a reference to the latest acked response from the ADS. - *

- * Usage: When nack a DiscoveryResponse this value is used to find the latest successfully processed - * DiscoveryResponse. Information sent in the nack request will contain information about this response value. - *

- */ - private DiscoveryResponse latestACKed; - - /** - * Node struct for the discovery client - */ - private final Node node; - - private ApplicationMappingDiscoveryClient(String host, String hostname, int port) { - this.host = host; - this.hostname = hostname; - this.port = port; - this.subscriptionDataStore = SubscriptionDataStoreImpl.getInstance(); - initConnection(); - this.node = XDSCommonUtils.generateXDSNode(AdapterConstants.COMMON_ENFORCER_LABEL); - this.latestACKed = DiscoveryResponse.getDefaultInstance(); - } - - private void initConnection() { - if (GRPCUtils.isReInitRequired(channel)) { - if (channel != null && !channel.isShutdown()) { - channel.shutdownNow(); - do { - try { - channel.awaitTermination(100, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - logger.error("Application mapping discovery channel shutdown wait was interrupted", e); - } - } while (!channel.isShutdown()); - } - this.channel = GRPCUtils.createSecuredChannel(logger, host, port, hostname); - this.stub = ApplicationMappingDiscoveryServiceGrpc.newStub(channel); - } else if (channel.getState(true) == ConnectivityState.READY) { - XdsSchedulerManager.getInstance().stopApplicationMappingDiscoveryScheduling(); - } - } - - public static ApplicationMappingDiscoveryClient getInstance() { - if (instance == null) { - String sdsHost = ConfigHolder.getInstance().getEnvVarConfig().getCommonControllerHost(); - String sdsHostname = ConfigHolder.getInstance().getEnvVarConfig().getCommonControllerHostname(); - int sdsPort = Integer.parseInt(ConfigHolder.getInstance().getEnvVarConfig().getCommonControllerXdsPort()); - instance = new ApplicationMappingDiscoveryClient(sdsHost, sdsHostname, sdsPort); - } - return instance; - } - - public void run() { - initConnection(); - watchApplicationMappings(); - } - - public void watchApplicationMappings() { - // TODO: (Praminda) implement a deadline with retries - reqObserver = stub.streamApplicationMappings(new StreamObserver() { - @Override - public void onNext(DiscoveryResponse response) { - logger.info("Application Mapping event received with version : " + response.getVersionInfo()); - logger.debug("Received Application Mapping discovery response " + response); - XdsSchedulerManager.getInstance().stopApplicationMappingDiscoveryScheduling(); - latestReceived = response; - try { - List applicationMappingList = new ArrayList<>(); - for (Any res : response.getResourcesList()) { - applicationMappingList.addAll(res.unpack(ApplicationMappingList.class).getListList()); - } - subscriptionDataStore.addApplicationMappings(applicationMappingList); - logger.info("Number of application mappings received : " + applicationMappingList.size()); - ack(); - } catch (Exception e) { - // catching generic error here to wrap any grpc communication errors in the runtime - onError(e); - } - } - - @Override - public void onError(Throwable throwable) { - logger.error("Error occurred during Application Mappings discovery", throwable); - XdsSchedulerManager.getInstance().startApplicationMappingDiscoveryScheduling(); - nack(throwable); - } - - @Override - public void onCompleted() { - logger.info("Completed receiving Application Mapping data"); - } - }); - - try { - DiscoveryRequest req = DiscoveryRequest.newBuilder() - .setNode(node) - .setVersionInfo(latestACKed.getVersionInfo()) - .setTypeUrl(Constants.APPLICATION_MAPPING_LIST_TYPE_URL).build(); - reqObserver.onNext(req); - logger.debug("Sent Discovery request for type url: " + Constants.APPLICATION_MAPPING_LIST_TYPE_URL); - - } catch (Exception e) { - logger.error("Unexpected error occurred in Application Mapping discovery service", e); - reqObserver.onError(e); - } - } - - /** - * Send acknowledgement of successfully processed DiscoveryResponse from the xDS server. This is part of the xDS - * communication protocol. - */ - private void ack() { - DiscoveryRequest req = DiscoveryRequest.newBuilder() - .setNode(node) - .setVersionInfo(latestReceived.getVersionInfo()) - .setResponseNonce(latestReceived.getNonce()) - .setTypeUrl(Constants.APPLICATION_MAPPING_LIST_TYPE_URL).build(); - reqObserver.onNext(req); - latestACKed = latestReceived; - } - - private void nack(Throwable e) { - if (latestReceived == null) { - return; - } - DiscoveryRequest req = DiscoveryRequest.newBuilder() - .setNode(node) - .setVersionInfo(latestACKed.getVersionInfo()) - .setResponseNonce(latestReceived.getNonce()) - .setTypeUrl(Constants.APPLICATION_MAPPING_LIST_TYPE_URL) - .setErrorDetail(Status.newBuilder().setMessage(e.getMessage())) - .build(); - reqObserver.onNext(req); - } -} diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/ApplicationPolicyDiscoveryClient.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/ApplicationPolicyDiscoveryClient.java deleted file mode 100644 index 1a63aa033..000000000 --- a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/ApplicationPolicyDiscoveryClient.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2021, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 LLC. licenses this file to you 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. - */ - -package org.wso2.apk.enforcer.discovery; - -import com.google.protobuf.Any; -import com.google.rpc.Status; -import io.envoyproxy.envoy.config.core.v3.Node; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryRequest; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryResponse; -import io.grpc.ConnectivityState; -import io.grpc.ManagedChannel; -import io.grpc.stub.StreamObserver; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.wso2.apk.enforcer.discovery.service.subscription.ApplicationPolicyDiscoveryServiceGrpc; -import org.wso2.apk.enforcer.discovery.subscription.ApplicationPolicy; -import org.wso2.apk.enforcer.discovery.subscription.ApplicationPolicyList; -import org.wso2.apk.enforcer.config.ConfigHolder; -import org.wso2.apk.enforcer.constants.AdapterConstants; -import org.wso2.apk.enforcer.constants.Constants; -import org.wso2.apk.enforcer.discovery.common.XDSCommonUtils; -import org.wso2.apk.enforcer.discovery.scheduler.XdsSchedulerManager; -import org.wso2.apk.enforcer.subscription.SubscriptionDataStoreImpl; -import org.wso2.apk.enforcer.util.GRPCUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -/** - * Client to communicate with Application Policy discovery service at the adapter. - */ -public class ApplicationPolicyDiscoveryClient implements Runnable { - private static final Logger logger = LogManager.getLogger(ApplicationPolicyDiscoveryClient.class); - private static ApplicationPolicyDiscoveryClient instance; - private ManagedChannel channel; - private ApplicationPolicyDiscoveryServiceGrpc.ApplicationPolicyDiscoveryServiceStub stub; - private StreamObserver reqObserver; - private final SubscriptionDataStoreImpl subscriptionDataStore; - private final String host; - private final String hostname; - private final int port; - - /** - * This is a reference to the latest received response from the ADS. - *

- * Usage: When ack/nack a DiscoveryResponse this value is used to identify the latest received DiscoveryResponse - * which may not have been acked/nacked so far. - *

- */ - - private DiscoveryResponse latestReceived; - /** - * This is a reference to the latest acked response from the ADS. - *

- * Usage: When nack a DiscoveryResponse this value is used to find the latest successfully processed - * DiscoveryResponse. Information sent in the nack request will contain information about this response value. - *

- */ - private DiscoveryResponse latestACKed; - - /** - * Node struct for the discovery client - */ - private final Node node; - - private ApplicationPolicyDiscoveryClient(String host, String hostname, int port) { - this.host = host; - this.hostname = hostname; - this.port = port; - this.subscriptionDataStore = SubscriptionDataStoreImpl.getInstance(); - initConnection(); - this.node = XDSCommonUtils.generateXDSNode(AdapterConstants.COMMON_ENFORCER_LABEL); - this.latestACKed = DiscoveryResponse.getDefaultInstance(); - } - - private void initConnection() { - if (GRPCUtils.isReInitRequired(channel)) { - if (channel != null && !channel.isShutdown()) { - channel.shutdownNow(); - do { - try { - channel.awaitTermination(100, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - logger.error("Application policy discovery channel shutdown wait was interrupted", e); - } - } while (!channel.isShutdown()); - } - this.channel = GRPCUtils.createSecuredChannel(logger, host, port, hostname); - this.stub = ApplicationPolicyDiscoveryServiceGrpc.newStub(channel); - } else if (channel.getState(true) == ConnectivityState.READY) { - XdsSchedulerManager.getInstance().stopApplicationPolicyDiscoveryScheduling(); - } - } - - public static ApplicationPolicyDiscoveryClient getInstance() { - if (instance == null) { - String sdsHost = ConfigHolder.getInstance().getEnvVarConfig().getAdapterHost(); - String sdsHostname = ConfigHolder.getInstance().getEnvVarConfig().getAdapterHostname(); - int sdsPort = Integer.parseInt(ConfigHolder.getInstance().getEnvVarConfig().getAdapterXdsPort()); - instance = new ApplicationPolicyDiscoveryClient(sdsHost, sdsHostname, sdsPort); - } - return instance; - } - - public void run() { - initConnection(); - watchApplicationPolicies(); - } - - public void watchApplicationPolicies() { - // TODO: (Praminda) implement a deadline with retries - reqObserver = stub.streamApplicationPolicies(new StreamObserver() { - @Override - public void onNext(DiscoveryResponse response) { - logger.info("Application policy event received with version : " + response.getVersionInfo()); - logger.debug("Received Application Policy discovery response " + response); - XdsSchedulerManager.getInstance().stopApplicationPolicyDiscoveryScheduling(); - latestReceived = response; - try { - List applicationPolicyList = new ArrayList<>(); - for (Any res : response.getResourcesList()) { - applicationPolicyList.addAll(res.unpack(ApplicationPolicyList.class).getListList()); - } - subscriptionDataStore.addApplicationPolicies(applicationPolicyList); - logger.info("Number of application policies received : " + applicationPolicyList.size()); - ack(); - } catch (Exception e) { - // catching generic error here to wrap any grpc communication errors in the runtime - onError(e); - } - } - - @Override - public void onError(Throwable throwable) { - logger.error("Error occurred during Application Policy discovery", throwable); - XdsSchedulerManager.getInstance().startApplicationPolicyDiscoveryScheduling(); - nack(throwable); - } - - @Override - public void onCompleted() { - logger.info("Completed receiving Application Policy data"); - } - }); - - try { - DiscoveryRequest req = DiscoveryRequest.newBuilder() - .setNode(node) - .setVersionInfo(latestACKed.getVersionInfo()) - .setTypeUrl(Constants.APPLICATION_POLICY_LIST_TYPE_URL).build(); - reqObserver.onNext(req); - logger.debug("Sent Discovery request for type url: " + Constants.APPLICATION_POLICY_LIST_TYPE_URL); - - } catch (Exception e) { - logger.error("Unexpected error occurred in Application Policy discovery service", e); - reqObserver.onError(e); - } - } - - /** - * Send acknowledgement of successfully processed DiscoveryResponse from the xDS server. This is part of the xDS - * communication protocol. - */ - private void ack() { - DiscoveryRequest req = DiscoveryRequest.newBuilder() - .setNode(node) - .setVersionInfo(latestReceived.getVersionInfo()) - .setResponseNonce(latestReceived.getNonce()) - .setTypeUrl(Constants.APPLICATION_POLICY_LIST_TYPE_URL).build(); - reqObserver.onNext(req); - latestACKed = latestReceived; - } - - private void nack(Throwable e) { - if (latestReceived == null) { - return; - } - DiscoveryRequest req = DiscoveryRequest.newBuilder() - .setNode(node) - .setVersionInfo(latestACKed.getVersionInfo()) - .setResponseNonce(latestReceived.getNonce()) - .setTypeUrl(Constants.APPLICATION_POLICY_LIST_TYPE_URL) - .setErrorDetail(Status.newBuilder().setMessage(e.getMessage())) - .build(); - reqObserver.onNext(req); - } -} diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/SubscriptionDiscoveryClient.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/SubscriptionDiscoveryClient.java deleted file mode 100644 index 61c317b63..000000000 --- a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/SubscriptionDiscoveryClient.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2021, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 LLC. licenses this file to you 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. - */ - -package org.wso2.apk.enforcer.discovery; - -import com.google.protobuf.Any; -import com.google.rpc.Status; -import io.envoyproxy.envoy.config.core.v3.Node; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryRequest; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryResponse; -import io.grpc.ConnectivityState; -import io.grpc.ManagedChannel; -import io.grpc.stub.StreamObserver; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.wso2.apk.enforcer.discovery.service.subscription.SubscriptionDiscoveryServiceGrpc; -import org.wso2.apk.enforcer.discovery.subscription.Subscription; -import org.wso2.apk.enforcer.discovery.subscription.SubscriptionList; -import org.wso2.apk.enforcer.config.ConfigHolder; -import org.wso2.apk.enforcer.constants.AdapterConstants; -import org.wso2.apk.enforcer.constants.Constants; -import org.wso2.apk.enforcer.discovery.common.XDSCommonUtils; -import org.wso2.apk.enforcer.discovery.scheduler.XdsSchedulerManager; -import org.wso2.apk.enforcer.subscription.SubscriptionDataStoreImpl; -import org.wso2.apk.enforcer.util.GRPCUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -/** - * Client to communicate with Subscription discovery service at the common-controller. - */ -public class SubscriptionDiscoveryClient implements Runnable { - private static final Logger logger = LogManager.getLogger(SubscriptionDiscoveryClient.class); - private static SubscriptionDiscoveryClient instance; - private ManagedChannel channel; - private SubscriptionDiscoveryServiceGrpc.SubscriptionDiscoveryServiceStub stub; - private StreamObserver reqObserver; - private final SubscriptionDataStoreImpl subscriptionDataStore; - private final String host; - private final String hostname; - private final int port; - - /** - * This is a reference to the latest received response from the ADS. - *

- * Usage: When ack/nack a DiscoveryResponse this value is used to identify the latest received DiscoveryResponse - * which may not have been acked/nacked so far. - *

- */ - - private DiscoveryResponse latestReceived; - /** - * This is a reference to the latest acked response from the ADS. - *

- * Usage: When nack a DiscoveryResponse this value is used to find the latest successfully processed - * DiscoveryResponse. Information sent in the nack request will contain information about this response value. - *

- */ - private DiscoveryResponse latestACKed; - /** - * Node struct for the discovery client - */ - private final Node node; - - private SubscriptionDiscoveryClient(String host, String hostname, int port) { - this.host = host; - this.hostname = hostname; - this.port = port; - this.subscriptionDataStore = SubscriptionDataStoreImpl.getInstance(); - initConnection(); - this.node = XDSCommonUtils.generateXDSNode(AdapterConstants.COMMON_ENFORCER_LABEL); - this.latestACKed = DiscoveryResponse.getDefaultInstance(); - } - - private void initConnection() { - if (GRPCUtils.isReInitRequired(channel)) { - if (channel != null && !channel.isShutdown()) { - channel.shutdownNow(); - do { - try { - channel.awaitTermination(100, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - logger.error("Subscription discovery channel shutdown wait was interrupted", e); - } - } while (!channel.isShutdown()); - } - this.channel = GRPCUtils.createSecuredChannel(logger, host, port, hostname); - this.stub = SubscriptionDiscoveryServiceGrpc.newStub(channel); - } else if (channel.getState(true) == ConnectivityState.READY) { - XdsSchedulerManager.getInstance().stopSubscriptionDiscoveryScheduling(); - } - } - - public static SubscriptionDiscoveryClient getInstance() { - if (instance == null) { - String sdsHost = ConfigHolder.getInstance().getEnvVarConfig().getCommonControllerHost(); - String sdsHostname = ConfigHolder.getInstance().getEnvVarConfig().getCommonControllerHostname(); - int sdsPort = Integer.parseInt(ConfigHolder.getInstance().getEnvVarConfig().getCommonControllerXdsPort()); - instance = new SubscriptionDiscoveryClient(sdsHost, sdsHostname, sdsPort); - } - return instance; - } - - public void run() { - initConnection(); - watchSubscriptions(); - } - - public void watchSubscriptions() { - // TODO: (Praminda) implement a deadline with retries - reqObserver = stub.streamSubscriptions(new StreamObserver() { - @Override - public void onNext(DiscoveryResponse response) { - logger.info("Subscription event received with version : " + response.getVersionInfo()); - logger.debug("Received Subscription discovery response " + response); - XdsSchedulerManager.getInstance().stopSubscriptionDiscoveryScheduling(); - latestReceived = response; - try { - List subscriptionList = new ArrayList<>(); - for (Any res : response.getResourcesList()) { - subscriptionList.addAll(res.unpack(SubscriptionList.class).getListList()); - } - subscriptionDataStore.addSubscriptions(subscriptionList); - logger.info("Number of subscriptions received : " + subscriptionList.size()); - ack(); - - } catch (Exception e) { - // catching generic error here to wrap any grpc communication errors in the runtime - onError(e); - } - } - - @Override - public void onError(Throwable throwable) { - logger.error("Error occurred during Subscription discovery", throwable); - XdsSchedulerManager.getInstance().startSubscriptionDiscoveryScheduling(); - nack(throwable); - } - - @Override - public void onCompleted() { - logger.info("Completed receiving Subscription data"); - } - }); - - try { - DiscoveryRequest req = DiscoveryRequest.newBuilder() - .setNode(node) - .setVersionInfo(latestACKed.getVersionInfo()) - .setTypeUrl(Constants.SUBSCRIPTION_LIST_TYPE_URL).build(); - reqObserver.onNext(req); - logger.debug("Sent Discovery request for type url: " + Constants.SUBSCRIPTION_LIST_TYPE_URL); - - } catch (Exception e) { - logger.error("Unexpected error occurred in API discovery service", e); - reqObserver.onError(e); - } - } - - /** - * Send acknowledgement of successfully processed DiscoveryResponse from the xDS server. This is part of the xDS - * communication protocol. - */ - private void ack() { - DiscoveryRequest req = DiscoveryRequest.newBuilder() - .setNode(node) - .setVersionInfo(latestReceived.getVersionInfo()) - .setResponseNonce(latestReceived.getNonce()) - .setTypeUrl(Constants.SUBSCRIPTION_LIST_TYPE_URL).build(); - reqObserver.onNext(req); - latestACKed = latestReceived; - } - - private void nack(Throwable e) { - if (latestReceived == null) { - return; - } - DiscoveryRequest req = DiscoveryRequest.newBuilder() - .setNode(node) - .setVersionInfo(latestACKed.getVersionInfo()) - .setResponseNonce(latestReceived.getNonce()) - .setTypeUrl(Constants.SUBSCRIPTION_LIST_TYPE_URL) - .setErrorDetail(Status.newBuilder().setMessage(e.getMessage())) - .build(); - reqObserver.onNext(req); - } -} diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/SubscriptionPolicyDiscoveryClient.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/SubscriptionPolicyDiscoveryClient.java deleted file mode 100644 index 3498b9c36..000000000 --- a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/SubscriptionPolicyDiscoveryClient.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2021, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 LLC. licenses this file to you 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. - */ - -package org.wso2.apk.enforcer.discovery; - -import com.google.protobuf.Any; -import com.google.rpc.Status; -import io.envoyproxy.envoy.config.core.v3.Node; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryRequest; -import io.envoyproxy.envoy.service.discovery.v3.DiscoveryResponse; -import io.grpc.ConnectivityState; -import io.grpc.ManagedChannel; -import io.grpc.stub.StreamObserver; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.wso2.apk.enforcer.discovery.service.subscription.SubscriptionPolicyDiscoveryServiceGrpc; -import org.wso2.apk.enforcer.discovery.subscription.SubscriptionPolicy; -import org.wso2.apk.enforcer.discovery.subscription.SubscriptionPolicyList; -import org.wso2.apk.enforcer.config.ConfigHolder; -import org.wso2.apk.enforcer.constants.AdapterConstants; -import org.wso2.apk.enforcer.constants.Constants; -import org.wso2.apk.enforcer.discovery.common.XDSCommonUtils; -import org.wso2.apk.enforcer.discovery.scheduler.XdsSchedulerManager; -import org.wso2.apk.enforcer.subscription.SubscriptionDataStoreImpl; -import org.wso2.apk.enforcer.util.GRPCUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -/** - * Client to communicate with Subscription Policy discovery service at the adapter. - */ -public class SubscriptionPolicyDiscoveryClient implements Runnable { - private static final Logger logger = LogManager.getLogger(SubscriptionPolicyDiscoveryClient.class); - private static SubscriptionPolicyDiscoveryClient instance; - private ManagedChannel channel; - private SubscriptionPolicyDiscoveryServiceGrpc.SubscriptionPolicyDiscoveryServiceStub stub; - private StreamObserver reqObserver; - private final SubscriptionDataStoreImpl subscriptionDataStore; - private final String host; - private final String hostname; - private final int port; - - /** - * This is a reference to the latest received response from the ADS. - *

- * Usage: When ack/nack a DiscoveryResponse this value is used to identify the latest received DiscoveryResponse - * which may not have been acked/nacked so far. - *

- */ - - private DiscoveryResponse latestReceived; - /** - * This is a reference to the latest acked response from the ADS. - *

- * Usage: When nack a DiscoveryResponse this value is used to find the latest successfully processed - * DiscoveryResponse. Information sent in the nack request will contain information about this response value. - *

- */ - private DiscoveryResponse latestACKed; - /** - * Node struct for the discovery client - */ - private final Node node; - - private SubscriptionPolicyDiscoveryClient(String host, String hostname, int port) { - this.host = host; - this.hostname = hostname; - this.port = port; - this.subscriptionDataStore = SubscriptionDataStoreImpl.getInstance(); - initConnection(); - this.node = XDSCommonUtils.generateXDSNode(AdapterConstants.COMMON_ENFORCER_LABEL); - this.latestACKed = DiscoveryResponse.getDefaultInstance(); - } - - private void initConnection() { - if (GRPCUtils.isReInitRequired(channel)) { - if (channel != null && !channel.isShutdown()) { - channel.shutdownNow(); - do { - try { - channel.awaitTermination(100, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - logger.error("Subscription policy discovery channel shutdown wait was interrupted", e); - } - } while (!channel.isShutdown()); - } - this.channel = GRPCUtils.createSecuredChannel(logger, host, port, hostname); - this.stub = SubscriptionPolicyDiscoveryServiceGrpc.newStub(channel); - } else if (channel.getState(true) == ConnectivityState.READY) { - XdsSchedulerManager.getInstance().stopSubscriptionPolicyDiscoveryScheduling(); - } - } - - public static SubscriptionPolicyDiscoveryClient getInstance() { - if (instance == null) { - String sdsHost = ConfigHolder.getInstance().getEnvVarConfig().getAdapterHost(); - String sdsHostname = ConfigHolder.getInstance().getEnvVarConfig().getAdapterHostname(); - int sdsPort = Integer.parseInt(ConfigHolder.getInstance().getEnvVarConfig().getAdapterXdsPort()); - instance = new SubscriptionPolicyDiscoveryClient(sdsHost, sdsHostname, sdsPort); - } - return instance; - } - - public void run() { - initConnection(); - watchSubscriptionPolicies(); - } - - public void watchSubscriptionPolicies() { - // TODO: (Praminda) implement a deadline with retries - reqObserver = stub.streamSubscriptionPolicies(new StreamObserver<>() { - @Override - public void onNext(DiscoveryResponse response) { - logger.info("Subscription policy event received with version : " + response.getVersionInfo()); - logger.debug("Received Subscription policy discovery response " + response); - XdsSchedulerManager.getInstance().stopSubscriptionPolicyDiscoveryScheduling(); - latestReceived = response; - try { - List subscriptionPolicyList = new ArrayList<>(); - for (Any res : response.getResourcesList()) { - subscriptionPolicyList.addAll(res.unpack(SubscriptionPolicyList.class).getListList()); - } - subscriptionDataStore.addSubscriptionPolicies(subscriptionPolicyList); - logger.info("Number of subscription policies received : " + subscriptionPolicyList.size()); - ack(); - } catch (Exception e) { - // catching generic error here to wrap any grpc communication errors in the runtime - onError(e); - } - } - - @Override - public void onError(Throwable throwable) { - logger.error("Error occurred during Subscription discovery", throwable); - XdsSchedulerManager.getInstance().startSubscriptionPolicyDiscoveryScheduling(); - nack(throwable); - } - - @Override - public void onCompleted() { - logger.info("Completed receiving Subscription data"); - } - }); - - try { - DiscoveryRequest req = DiscoveryRequest.newBuilder() - .setNode(node) - .setVersionInfo(latestACKed.getVersionInfo()) - .setTypeUrl(Constants.SUBSCRIPTION_POLICY_LIST_TYPE_URL).build(); - reqObserver.onNext(req); - logger.debug("Sent Discovery request for type url: " + Constants.SUBSCRIPTION_POLICY_LIST_TYPE_URL); - - } catch (Exception e) { - logger.error("Unexpected error occurred in API discovery service", e); - reqObserver.onError(e); - } - } - - /** - * Send acknowledgement of successfully processed DiscoveryResponse from the xDS server. This is part of the xDS - * communication protocol. - */ - private void ack() { - DiscoveryRequest req = DiscoveryRequest.newBuilder() - .setNode(node) - .setVersionInfo(latestReceived.getVersionInfo()) - .setResponseNonce(latestReceived.getNonce()) - .setTypeUrl(Constants.SUBSCRIPTION_POLICY_LIST_TYPE_URL).build(); - reqObserver.onNext(req); - latestACKed = latestReceived; - } - - private void nack(Throwable e) { - if (latestReceived == null) { - return; - } - DiscoveryRequest req = DiscoveryRequest.newBuilder() - .setNode(node) - .setVersionInfo(latestACKed.getVersionInfo()) - .setResponseNonce(latestReceived.getNonce()) - .setTypeUrl(Constants.SUBSCRIPTION_POLICY_LIST_TYPE_URL) - .setErrorDetail(Status.newBuilder().setMessage(e.getMessage())) - .build(); - reqObserver.onNext(req); - } -} diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/scheduler/XdsSchedulerManager.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/scheduler/XdsSchedulerManager.java index a23c03879..5440c8bda 100644 --- a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/scheduler/XdsSchedulerManager.java +++ b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/discovery/scheduler/XdsSchedulerManager.java @@ -21,15 +21,9 @@ import org.wso2.apk.enforcer.config.EnvVarConfig; import org.wso2.apk.enforcer.discovery.ApiDiscoveryClient; import org.wso2.apk.enforcer.discovery.ApiListDiscoveryClient; -import org.wso2.apk.enforcer.discovery.ApplicationDiscoveryClient; -import org.wso2.apk.enforcer.discovery.ApplicationKeyMappingDiscoveryClient; -import org.wso2.apk.enforcer.discovery.ApplicationMappingDiscoveryClient; -import org.wso2.apk.enforcer.discovery.ApplicationPolicyDiscoveryClient; import org.wso2.apk.enforcer.discovery.ConfigDiscoveryClient; import org.wso2.apk.enforcer.discovery.JWTIssuerDiscoveryClient; import org.wso2.apk.enforcer.discovery.RevokedTokenDiscoveryClient; -import org.wso2.apk.enforcer.discovery.SubscriptionDiscoveryClient; -import org.wso2.apk.enforcer.discovery.SubscriptionPolicyDiscoveryClient; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -40,23 +34,16 @@ * Manages all the scheduling tasks that runs for retrying discovery requests. */ public class XdsSchedulerManager { + private static int retryPeriod; private static volatile XdsSchedulerManager instance; private static ScheduledExecutorService discoveryClientScheduler; private ScheduledFuture apiDiscoveryScheduledFuture; private ScheduledFuture apiDiscoveryListScheduledFuture; - private ScheduledFuture applicationDiscoveryScheduledFuture; private ScheduledFuture jwtIssuerDiscoveryScheduledFuture; - private ScheduledFuture applicationKeyMappingDiscoveryScheduledFuture; - private ScheduledFuture applicationMappingDiscoveryScheduledFuture; - private ScheduledFuture keyManagerDiscoveryScheduledFuture; private ScheduledFuture revokedTokenDiscoveryScheduledFuture; - private ScheduledFuture subscriptionDiscoveryScheduledFuture; - private ScheduledFuture throttleDataDiscoveryScheduledFuture; private ScheduledFuture configDiscoveryScheduledFuture; - private ScheduledFuture applicationPolicyDiscoveryScheduledFuture; - private ScheduledFuture subscriptionPolicyDiscoveryScheduledFuture; public static XdsSchedulerManager getInstance() { if (instance == null) { @@ -97,49 +84,20 @@ public synchronized void stopAPIListDiscoveryScheduling() { } } - public synchronized void startApplicationDiscoveryScheduling() { - if (applicationDiscoveryScheduledFuture == null || applicationDiscoveryScheduledFuture.isDone()) { - applicationDiscoveryScheduledFuture = discoveryClientScheduler - .scheduleWithFixedDelay(ApplicationDiscoveryClient.getInstance(), 1, retryPeriod, TimeUnit.SECONDS); - } - } - public synchronized void startJWTIssuerDiscoveryScheduling(){ + public synchronized void startJWTIssuerDiscoveryScheduling() { + if (jwtIssuerDiscoveryScheduledFuture == null || jwtIssuerDiscoveryScheduledFuture.isDone()) { jwtIssuerDiscoveryScheduledFuture = discoveryClientScheduler .scheduleWithFixedDelay(JWTIssuerDiscoveryClient.getInstance(), 1, retryPeriod, TimeUnit.SECONDS); } } - public synchronized void stopApplicationDiscoveryScheduling() { - if (applicationDiscoveryScheduledFuture != null && !applicationDiscoveryScheduledFuture.isDone()) { - applicationDiscoveryScheduledFuture.cancel(false); - } - } - public synchronized void stopJWTIssuerDiscoveryScheduling() { if (jwtIssuerDiscoveryScheduledFuture != null && !jwtIssuerDiscoveryScheduledFuture.isDone()) { jwtIssuerDiscoveryScheduledFuture.cancel(false); } } - public synchronized void startApplicationKeyMappingDiscoveryScheduling() { - if (applicationKeyMappingDiscoveryScheduledFuture == null || applicationKeyMappingDiscoveryScheduledFuture - .isDone()) { - applicationKeyMappingDiscoveryScheduledFuture = discoveryClientScheduler - .scheduleWithFixedDelay(ApplicationKeyMappingDiscoveryClient.getInstance(), 1, retryPeriod, - TimeUnit.SECONDS); - } - } - - public synchronized void stopApplicationKeyMappingDiscoveryScheduling() { - if (applicationKeyMappingDiscoveryScheduledFuture != null && !applicationKeyMappingDiscoveryScheduledFuture - .isDone()) { - applicationKeyMappingDiscoveryScheduledFuture.cancel(false); - } - } - - - public synchronized void startRevokedTokenDiscoveryScheduling() { if (revokedTokenDiscoveryScheduledFuture == null || revokedTokenDiscoveryScheduledFuture.isDone()) { revokedTokenDiscoveryScheduledFuture = discoveryClientScheduler @@ -154,20 +112,6 @@ public synchronized void stopRevokedTokenDiscoveryScheduling() { } } - public synchronized void startSubscriptionDiscoveryScheduling() { - if (subscriptionDiscoveryScheduledFuture == null || subscriptionDiscoveryScheduledFuture.isDone()) { - subscriptionDiscoveryScheduledFuture = discoveryClientScheduler - .scheduleWithFixedDelay(SubscriptionDiscoveryClient.getInstance(), 1, retryPeriod, - TimeUnit.SECONDS); - } - } - - public synchronized void stopSubscriptionDiscoveryScheduling() { - if (subscriptionDiscoveryScheduledFuture != null && !subscriptionDiscoveryScheduledFuture.isDone()) { - subscriptionDiscoveryScheduledFuture.cancel(false); - } - } - public synchronized void startConfigDiscoveryScheduling() { if (configDiscoveryScheduledFuture == null || configDiscoveryScheduledFuture.isDone()) { configDiscoveryScheduledFuture = discoveryClientScheduler @@ -182,47 +126,4 @@ public synchronized void stopConfigDiscoveryScheduling() { } } - public synchronized void startApplicationPolicyDiscoveryScheduling() { - if (applicationPolicyDiscoveryScheduledFuture == null || applicationPolicyDiscoveryScheduledFuture.isDone()) { - applicationPolicyDiscoveryScheduledFuture = discoveryClientScheduler - .scheduleWithFixedDelay(ApplicationPolicyDiscoveryClient.getInstance(), 1, retryPeriod, - TimeUnit.SECONDS); - } - } - - public synchronized void stopApplicationPolicyDiscoveryScheduling() { - if (applicationPolicyDiscoveryScheduledFuture != null && !applicationPolicyDiscoveryScheduledFuture.isDone()) { - applicationPolicyDiscoveryScheduledFuture.cancel(false); - } - } - - public synchronized void startSubscriptionPolicyDiscoveryScheduling() { - if (subscriptionPolicyDiscoveryScheduledFuture == null || subscriptionPolicyDiscoveryScheduledFuture.isDone()) { - subscriptionPolicyDiscoveryScheduledFuture = discoveryClientScheduler - .scheduleWithFixedDelay(SubscriptionPolicyDiscoveryClient.getInstance(), 1, retryPeriod, - TimeUnit.SECONDS); - } - } - - public synchronized void stopSubscriptionPolicyDiscoveryScheduling() { - if (subscriptionPolicyDiscoveryScheduledFuture != null && !subscriptionPolicyDiscoveryScheduledFuture - .isDone()) { - subscriptionPolicyDiscoveryScheduledFuture.cancel(false); - } - } - - public synchronized void startApplicationMappingDiscoveryScheduling() { - if (applicationMappingDiscoveryScheduledFuture == null || applicationMappingDiscoveryScheduledFuture.isDone()) { - applicationMappingDiscoveryScheduledFuture = discoveryClientScheduler - .scheduleWithFixedDelay(ApplicationMappingDiscoveryClient.getInstance(), 1, retryPeriod, - TimeUnit.SECONDS); - } - } - - public synchronized void stopApplicationMappingDiscoveryScheduling() { - if (applicationMappingDiscoveryScheduledFuture != null && !applicationMappingDiscoveryScheduledFuture - .isDone()) { - applicationMappingDiscoveryScheduledFuture.cancel(false); - } - } } diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/interceptor/opa/OPAClient.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/interceptor/opa/OPAClient.java index 15a39c414..3e013f76b 100644 --- a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/interceptor/opa/OPAClient.java +++ b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/interceptor/opa/OPAClient.java @@ -99,7 +99,7 @@ public boolean validateRequest(RequestContext requestContext, Map clientOptions = new HashMap<>(); + Map clientOptions = new HashMap<>(); FilterUtils.putToMapIfNotNull(clientOptions, FilterUtils.HTTPClientOptions.MAX_OPEN_CONNECTIONS, policyAttrib.get("maxOpenConnections")); FilterUtils.putToMapIfNotNull(clientOptions, FilterUtils.HTTPClientOptions.MAX_PER_ROUTE, @@ -135,7 +135,7 @@ private void loadRequestGenerators() { } private static String callOPAServer(String serverEp, String payload, String token, - Map clientOptions) throws OPASecurityException { + Map clientOptions) throws OPASecurityException { try { URL url = new URL(serverEp); KeyStore opaKeyStore = ConfigHolder.getInstance().getOpaKeyStore(); diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/ApplicationDto.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/ApplicationDto.java new file mode 100644 index 000000000..59aafe9db --- /dev/null +++ b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/ApplicationDto.java @@ -0,0 +1,70 @@ +package org.wso2.apk.enforcer.subscription; + +import java.io.Serializable; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Entity for keeping Application related information. Represents an Application in APK. + */ +public class ApplicationDto implements Serializable { + + private static final long serialVersionUID = 1L; + + private String uuid; + private String name; + private String owner; + private Map attributes = new ConcurrentHashMap<>(); + + private String organizationId; + + public String getUuid() { + + return uuid; + } + + public void setUuid(String uuid) { + + this.uuid = uuid; + } + + public String getName() { + + return name; + } + + public void setName(String name) { + + this.name = name; + } + + public String getOwner() { + + return owner; + } + + public void setOwner(String owner) { + + this.owner = owner; + } + + public Map getAttributes() { + + return attributes; + } + + public void setAttributes(Map attributes) { + + this.attributes = attributes; + } + + public String getOrganizationId() { + + return organizationId; + } + + public void setOrganizationId(String organizationId) { + + this.organizationId = organizationId; + } +} diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/ApplicationKeyMappingDTO.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/ApplicationKeyMappingDTO.java new file mode 100644 index 000000000..283f9da9e --- /dev/null +++ b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/ApplicationKeyMappingDTO.java @@ -0,0 +1,63 @@ +package org.wso2.apk.enforcer.subscription; + +import java.io.Serializable; + +public class ApplicationKeyMappingDTO implements Serializable { + + public String getApplicationUUID() { + + return applicationUUID; + } + + public void setApplicationUUID(String applicationUUID) { + + this.applicationUUID = applicationUUID; + } + + public String getSecurityScheme() { + + return securityScheme; + } + + public void setSecurityScheme(String securityScheme) { + + this.securityScheme = securityScheme; + } + + public String getApplicationIdentifier() { + + return applicationIdentifier; + } + + public void setApplicationIdentifier(String applicationIdentifier) { + + this.applicationIdentifier = applicationIdentifier; + } + + public String getKeyType() { + + return keyType; + } + + public void setKeyType(String keyType) { + + this.keyType = keyType; + } + + public String getEnvID() { + + return envID; + } + + public void setEnvID(String envID) { + + this.envID = envID; + } + + private String applicationUUID; + private String securityScheme; + private String applicationIdentifier; + private String keyType; + private String envID; + +} diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/ApplicationKeyMappingDtoList.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/ApplicationKeyMappingDtoList.java new file mode 100644 index 000000000..36ab9cba7 --- /dev/null +++ b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/ApplicationKeyMappingDtoList.java @@ -0,0 +1,13 @@ +package org.wso2.apk.enforcer.subscription; + +import java.util.ArrayList; +import java.util.List; + +public class ApplicationKeyMappingDtoList { +private List list = new ArrayList<>(); + + public List getList() { + + return list; + } +} diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/ApplicationListDto.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/ApplicationListDto.java new file mode 100644 index 000000000..333c3ad32 --- /dev/null +++ b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/ApplicationListDto.java @@ -0,0 +1,19 @@ +package org.wso2.apk.enforcer.subscription; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public class ApplicationListDto implements Serializable { +private List list = new ArrayList<>(); + + public List getList() { + + return list; + } + + public void setList(List list) { + + this.list = list; + } +} diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/ApplicationMappingDto.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/ApplicationMappingDto.java new file mode 100644 index 000000000..376266ab8 --- /dev/null +++ b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/ApplicationMappingDto.java @@ -0,0 +1,40 @@ +package org.wso2.apk.enforcer.subscription; + +import java.io.Serializable; + +public class ApplicationMappingDto implements Serializable { + private String uuid; + + public String getUuid() { + + return uuid; + } + + public void setUuid(String uuid) { + + this.uuid = uuid; + } + + public String getApplicationRef() { + + return applicationRef; + } + + public void setApplicationRef(String applicationRef) { + + this.applicationRef = applicationRef; + } + + public String getSubscriptionRef() { + + return subscriptionRef; + } + + public void setSubscriptionRef(String subscriptionRef) { + + this.subscriptionRef = subscriptionRef; + } + + private String applicationRef; + private String subscriptionRef; +} diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/ApplicationMappingDtoList.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/ApplicationMappingDtoList.java new file mode 100644 index 000000000..8b310b93a --- /dev/null +++ b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/ApplicationMappingDtoList.java @@ -0,0 +1,13 @@ +package org.wso2.apk.enforcer.subscription; + +import java.util.ArrayList; +import java.util.List; + +public class ApplicationMappingDtoList { +private List list = new ArrayList<>(); + + public List getList() { + + return list; + } +} diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/SubscribedAPIDto.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/SubscribedAPIDto.java new file mode 100644 index 000000000..0d35afa20 --- /dev/null +++ b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/SubscribedAPIDto.java @@ -0,0 +1,29 @@ +package org.wso2.apk.enforcer.subscription; + +import java.io.Serializable; + +public class SubscribedAPIDto implements Serializable { + + public String getName() { + + return name; + } + + public void setName(String name) { + + this.name = name; + } + + public String getVersion() { + + return version; + } + + public void setVersion(String version) { + + this.version = version; + } + + private String name; + private String version; +} diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/SubscriptionDataStore.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/SubscriptionDataStore.java index ddcb0ae40..18fe03df2 100644 --- a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/SubscriptionDataStore.java +++ b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/SubscriptionDataStore.java @@ -55,20 +55,14 @@ public interface SubscriptionDataStore { */ Subscription getSubscriptionById(String appUUID, String apiUUID); - void addSubscriptions(List subscriptionList); + void addSubscriptions(List subscriptionList); - void addApplications(List applicationList); + void addApplications(List applicationList); void addApis(List apisList); - void addApplicationPolicies( - List applicationPolicyList); - - void addSubscriptionPolicies( - List subscriptionPolicyList); - void addApplicationKeyMappings( - List applicationKeyMappingList); + List applicationKeyMappingList); /** * Filter the API map according to the provided parameters diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/SubscriptionDataStoreImpl.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/SubscriptionDataStoreImpl.java index 42f1ba786..7b17e2b6e 100644 --- a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/SubscriptionDataStoreImpl.java +++ b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/SubscriptionDataStoreImpl.java @@ -18,40 +18,39 @@ package org.wso2.apk.enforcer.subscription; +import feign.Feign; +import feign.gson.GsonDecoder; +import feign.gson.GsonEncoder; +import feign.slf4j.Slf4jLogger; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.wso2.apk.enforcer.commons.dto.ClaimMappingDto; import org.wso2.apk.enforcer.commons.dto.JWKSConfigurationDTO; import org.wso2.apk.enforcer.commons.exception.EnforcerException; +import org.wso2.apk.enforcer.config.ConfigHolder; import org.wso2.apk.enforcer.config.dto.ExtendedTokenIssuerDto; import org.wso2.apk.enforcer.constants.Constants; import org.wso2.apk.enforcer.discovery.ApiListDiscoveryClient; -import org.wso2.apk.enforcer.discovery.ApplicationDiscoveryClient; -import org.wso2.apk.enforcer.discovery.ApplicationKeyMappingDiscoveryClient; -import org.wso2.apk.enforcer.discovery.ApplicationMappingDiscoveryClient; -import org.wso2.apk.enforcer.discovery.ApplicationPolicyDiscoveryClient; import org.wso2.apk.enforcer.discovery.JWTIssuerDiscoveryClient; -import org.wso2.apk.enforcer.discovery.SubscriptionDiscoveryClient; -import org.wso2.apk.enforcer.discovery.SubscriptionPolicyDiscoveryClient; import org.wso2.apk.enforcer.discovery.subscription.APIs; import org.wso2.apk.enforcer.discovery.subscription.Certificate; import org.wso2.apk.enforcer.discovery.subscription.JWTIssuer; import org.wso2.apk.enforcer.models.API; -import org.wso2.apk.enforcer.models.ApiPolicy; import org.wso2.apk.enforcer.models.Application; import org.wso2.apk.enforcer.models.ApplicationKeyMapping; import org.wso2.apk.enforcer.models.ApplicationMapping; -import org.wso2.apk.enforcer.models.ApplicationPolicy; import org.wso2.apk.enforcer.models.SubscribedAPI; import org.wso2.apk.enforcer.models.Subscription; -import org.wso2.apk.enforcer.models.SubscriptionPolicy; import org.wso2.apk.enforcer.security.jwt.validator.JWTValidator; +import org.wso2.apk.enforcer.util.ApacheFeignHttpClient; +import org.wso2.apk.enforcer.util.FilterUtils; import org.wso2.apk.enforcer.util.TLSUtils; import java.io.IOException; import java.security.cert.CertificateException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -65,15 +64,6 @@ public class SubscriptionDataStoreImpl implements SubscriptionDataStore { private static final Logger log = LogManager.getLogger(SubscriptionDataStoreImpl.class); private static final SubscriptionDataStoreImpl instance = new SubscriptionDataStoreImpl(); - /** - * ENUM to hold type of policies. - */ - public enum PolicyType { - SUBSCRIPTION, - APPLICATION, - API - } - public static final String DELEM_PERIOD = ":"; // Maps for keeping Subscription related details. @@ -81,12 +71,10 @@ public enum PolicyType { private Map applicationMappingMap; private Map applicationMap; private Map apiMap; - private Map apiPolicyMap; - private Map subscriptionPolicyMap; - private Map appPolicyMap; private Map subscriptionMap; private Map> jwtValidatorMap; + SubscriptionValidationDataRetrievalRestClient subscriptionValidationDataRetrievalRestClient; SubscriptionDataStoreImpl() { @@ -99,12 +87,21 @@ public static SubscriptionDataStoreImpl getInstance() { public void initializeStore() { + String commonControllerHost = ConfigHolder.getInstance().getEnvVarConfig().getCommonControllerHost(); + String commonControllerHostname = ConfigHolder.getInstance().getEnvVarConfig().getCommonControllerHostname(); + int commonControllerRestPort = + Integer.parseInt(ConfigHolder.getInstance().getEnvVarConfig().getCommonControllerRestPort()); + subscriptionValidationDataRetrievalRestClient = Feign.builder() + .encoder(new GsonEncoder()) + .decoder(new GsonDecoder()) + .logger(new Slf4jLogger()) + .client(new ApacheFeignHttpClient(FilterUtils.getMutualSSLHttpClient("https", + Arrays.asList(commonControllerHost, commonControllerHostname)))) + .target(SubscriptionValidationDataRetrievalRestClient.class, + "https://" + commonControllerHost + ":" + commonControllerRestPort); this.applicationKeyMappingMap = new ConcurrentHashMap<>(); this.applicationMap = new ConcurrentHashMap<>(); this.apiMap = new ConcurrentHashMap<>(); - this.subscriptionPolicyMap = new ConcurrentHashMap<>(); - this.appPolicyMap = new ConcurrentHashMap<>(); - this.apiPolicyMap = new ConcurrentHashMap<>(); this.subscriptionMap = new ConcurrentHashMap<>(); this.applicationMappingMap = new ConcurrentHashMap<>(); this.jwtValidatorMap = new ConcurrentHashMap<>(); @@ -130,22 +127,51 @@ public Subscription getSubscriptionById(String appId, String apiId) { } private void initializeLoadingTasks() { - - SubscriptionDiscoveryClient.getInstance().watchSubscriptions(); - ApplicationDiscoveryClient.getInstance().watchApplications(); + loadSubscriptions(); + loadApplications(); + loadApplicationMappings(); + loadApplicationKeyMappings(); ApiListDiscoveryClient.getInstance().watchApiList(); - ApplicationPolicyDiscoveryClient.getInstance().watchApplicationPolicies(); - SubscriptionPolicyDiscoveryClient.getInstance().watchSubscriptionPolicies(); - ApplicationKeyMappingDiscoveryClient.getInstance().watchApplicationKeyMappings(); - ApplicationMappingDiscoveryClient.getInstance().watchApplicationMappings(); JWTIssuerDiscoveryClient.getInstance().watchJWTIssuers(); } - public void addSubscriptions(List subscriptionList) { + private void loadApplicationKeyMappings() { + new Thread(() -> { + ApplicationKeyMappingDtoList applicationKeyMappings = + subscriptionValidationDataRetrievalRestClient.getAllApplicationKeyMappings(); + addApplicationKeyMappings(applicationKeyMappings.getList()); + }).start(); + + } + + private void loadApplicationMappings() { + new Thread(() -> { + ApplicationMappingDtoList applicationMappings = subscriptionValidationDataRetrievalRestClient + .getAllApplicationMappings(); + addApplicationMappings(applicationMappings.getList()); + }).start(); + + } + + private void loadApplications(){ + new Thread(() -> { + ApplicationListDto applications = subscriptionValidationDataRetrievalRestClient.getAllApplications(); + addApplications(applications.getList()); + }).start(); + } + private void loadSubscriptions() { + + new Thread(() -> { + SubscriptionListDto subscriptions = subscriptionValidationDataRetrievalRestClient.getAllSubscriptions(); + addSubscriptions(subscriptions.getList()); + }).start(); + } + + public void addSubscriptions(List subscriptionList) { Map newSubscriptionMap = new ConcurrentHashMap<>(); - for (org.wso2.apk.enforcer.discovery.subscription.Subscription subscription : subscriptionList) { + for (SubscriptionDto subscription : subscriptionList) { SubscribedAPI subscribedAPI = new SubscribedAPI(); subscribedAPI.setName(subscription.getSubscribedApi().getName()); subscribedAPI.setVersion(subscription.getSubscribedApi().getVersion()); @@ -155,8 +181,6 @@ public void addSubscriptions(List applicationList) { + public void addApplications(List applicationList) { Map newApplicationMap = new ConcurrentHashMap<>(); - for (org.wso2.apk.enforcer.discovery.subscription.Application application : applicationList) { + for (ApplicationDto application: applicationList) { Application newApplication = new Application(); newApplication.setUUID(application.getUuid()); newApplication.setName(application.getName()); newApplication.setOwner(application.getOwner()); - application.getAttributesMap().forEach(newApplication::addAttribute); + application.getAttributes().forEach(newApplication::addAttribute); newApplicationMap.put(newApplication.getCacheKey(), newApplication); } @@ -208,57 +232,13 @@ public void addApis(List apisList) { this.apiMap = newApiMap; } - public void addApplicationPolicies( - List applicationPolicyList) { - - Map newAppPolicyMap = new ConcurrentHashMap<>(); - - for (org.wso2.apk.enforcer.discovery.subscription.ApplicationPolicy applicationPolicy : applicationPolicyList) { - ApplicationPolicy newApplicationPolicy = new ApplicationPolicy(); - newApplicationPolicy.setId(applicationPolicy.getId()); - newApplicationPolicy.setQuotaType(applicationPolicy.getQuotaType()); - newApplicationPolicy.setTenantId(applicationPolicy.getTenantId()); - newApplicationPolicy.setTierName(applicationPolicy.getName()); - - newAppPolicyMap.put(newApplicationPolicy.getCacheKey(), newApplicationPolicy); - } - if (log.isDebugEnabled()) { - log.debug("Total Application Policies in new cache: {}", newAppPolicyMap.size()); - } - this.appPolicyMap = newAppPolicyMap; - } - - public void addSubscriptionPolicies( - List subscriptionPolicyList) { - - Map newSubscriptionPolicyMap = new ConcurrentHashMap<>(); - - for (org.wso2.apk.enforcer.discovery.subscription.SubscriptionPolicy subscriptionPolicy : subscriptionPolicyList) { - SubscriptionPolicy newSubscriptionPolicy = new SubscriptionPolicy(); - newSubscriptionPolicy.setId(subscriptionPolicy.getId()); - newSubscriptionPolicy.setQuotaType(subscriptionPolicy.getQuotaType()); - newSubscriptionPolicy.setRateLimitCount(subscriptionPolicy.getRateLimitCount()); - newSubscriptionPolicy.setRateLimitTimeUnit(subscriptionPolicy.getRateLimitTimeUnit()); - newSubscriptionPolicy.setStopOnQuotaReach(subscriptionPolicy.getStopOnQuotaReach()); - newSubscriptionPolicy.setTenantId(subscriptionPolicy.getTenantId()); - newSubscriptionPolicy.setTierName(subscriptionPolicy.getName()); - newSubscriptionPolicy.setGraphQLMaxComplexity(subscriptionPolicy.getGraphQLMaxComplexity()); - newSubscriptionPolicy.setGraphQLMaxDepth(subscriptionPolicy.getGraphQLMaxDepth()); - - newSubscriptionPolicyMap.put(newSubscriptionPolicy.getCacheKey(), newSubscriptionPolicy); - } - if (log.isDebugEnabled()) { - log.debug("Total Subscription Policies in new cache: {}", newSubscriptionPolicyMap.size()); - } - this.subscriptionPolicyMap = newSubscriptionPolicyMap; - } - public void addApplicationKeyMappings( - List applicationKeyMappingList) { + List applicationKeyMappingList) { Map newApplicationKeyMappingMap = new ConcurrentHashMap<>(); - for (org.wso2.apk.enforcer.discovery.subscription.ApplicationKeyMapping applicationKeyMapping : applicationKeyMappingList) { + for (ApplicationKeyMappingDTO applicationKeyMapping : + applicationKeyMappingList) { ApplicationKeyMapping mapping = new ApplicationKeyMapping(); mapping.setApplicationUUID(applicationKeyMapping.getApplicationUUID()); mapping.setSecurityScheme(applicationKeyMapping.getSecurityScheme()); @@ -274,11 +254,11 @@ public void addApplicationKeyMappings( } public void addApplicationMappings( - List applicationMappingList) { + List applicationMappingList) { Map newApplicationMappingMap = new ConcurrentHashMap<>(); - for (org.wso2.apk.enforcer.discovery.subscription.ApplicationMapping applicationMapping : + for (ApplicationMappingDto applicationMapping : applicationMappingList) { ApplicationMapping appMapping = new ApplicationMapping(); appMapping.setUuid(applicationMapping.getUuid()); @@ -307,7 +287,7 @@ public API getMatchingAPI(String context, String version) { @Override public ApplicationKeyMapping getMatchingApplicationKeyMapping(String applicationIdentifier, String keyType, - String securityScheme) { + String securityScheme) { for (ApplicationKeyMapping applicationKeyMapping : applicationKeyMappingMap.values()) { boolean isApplicationIdentifierMatching = false; @@ -339,6 +319,7 @@ public ApplicationKeyMapping getMatchingApplicationKeyMapping(String application @Override public ApplicationMapping getMatchingApplicationMapping(String uuid) { + for (ApplicationMapping applicationMapping : applicationMappingMap.values()) { if (StringUtils.isNotEmpty(uuid)) { if (applicationMapping.getApplicationRef().equals(uuid)) { @@ -351,6 +332,7 @@ public ApplicationMapping getMatchingApplicationMapping(String uuid) { @Override public Application getMatchingApplication(String uuid) { + for (Application application : applicationMap.values()) { if (StringUtils.isNotEmpty(uuid)) { if (application.getUUID().equals(uuid)) { @@ -363,6 +345,7 @@ public Application getMatchingApplication(String uuid) { @Override public Subscription getMatchingSubscription(String uuid) { + for (Subscription subscription : subscriptionMap.values()) { if (StringUtils.isNotEmpty(uuid)) { if (subscription.getSubscriptionId().equals(uuid)) { @@ -461,9 +444,9 @@ private List getEnvironments(JWTIssuer jwtIssuer) { return environmentsList; } - private String getMapKey(String environment, String issuer) { + private String getMapKey(String environment, String issuer) { + return environment + DELEM_PERIOD + issuer; } - } diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/SubscriptionDto.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/SubscriptionDto.java new file mode 100644 index 000000000..c2e7133c1 --- /dev/null +++ b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/SubscriptionDto.java @@ -0,0 +1,55 @@ +package org.wso2.apk.enforcer.subscription; + +import java.io.Serializable; + +/** + * Entity for keeping Application related information. Represents an Application in APK. + */ +public class SubscriptionDto implements Serializable { + + private static final long serialVersionUID = 1L; + private String uuid; + private String organization; + private String subStatus; + private SubscribedAPIDto subscribedApi; + + public String getUuid() { + + return uuid; + } + + public void setUuid(String uuid) { + + this.uuid = uuid; + } + + public String getOrganization() { + + return organization; + } + + public void setOrganization(String organization) { + + this.organization = organization; + } + + public String getSubStatus() { + + return subStatus; + } + + public void setSubStatus(String subStatus) { + + this.subStatus = subStatus; + } + + public SubscribedAPIDto getSubscribedApi() { + + return subscribedApi; + } + + public void setSubscribedApi(SubscribedAPIDto subscribedApi) { + + this.subscribedApi = subscribedApi; + } +} \ No newline at end of file diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/SubscriptionListDto.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/SubscriptionListDto.java new file mode 100644 index 000000000..e89dbc1fb --- /dev/null +++ b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/SubscriptionListDto.java @@ -0,0 +1,14 @@ +package org.wso2.apk.enforcer.subscription; + +import java.util.ArrayList; +import java.util.List; + +public class SubscriptionListDto { + + private List list = new ArrayList<>(); + + public List getList() { + + return list; + } +} diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/SubscriptionValidationDataRetrievalRestClient.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/SubscriptionValidationDataRetrievalRestClient.java new file mode 100644 index 000000000..95af008b6 --- /dev/null +++ b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/subscription/SubscriptionValidationDataRetrievalRestClient.java @@ -0,0 +1,23 @@ +package org.wso2.apk.enforcer.subscription; +import feign.Headers; +import feign.Param; +import feign.RequestLine; + +public interface SubscriptionValidationDataRetrievalRestClient { + + @RequestLine("GET /applications") + @Headers("Content-Type: application/json") + ApplicationListDto getAllApplications(); + + @RequestLine("GET /subscriptions") + @Headers("Content-Type: application/json") + SubscriptionListDto getAllSubscriptions(); + + @RequestLine("GET /applicationmappings") + @Headers("Content-Type: application/json") + ApplicationMappingDtoList getAllApplicationMappings(); + + @RequestLine("GET /applicationkeymappings") + @Headers("Content-Type: application/json") + ApplicationKeyMappingDtoList getAllApplicationKeyMappings(); +} diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/util/ApacheFeignHttpClient.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/util/ApacheFeignHttpClient.java new file mode 100644 index 000000000..398fad2b2 --- /dev/null +++ b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/util/ApacheFeignHttpClient.java @@ -0,0 +1,238 @@ +package org.wso2.apk.enforcer.util;/* + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) 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. + */ + + + +import feign.Client; +import feign.Request; +import feign.Response; +import feign.Util; +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.StatusLine; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.Configurable; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.client.methods.RequestBuilder; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.client.utils.URLEncodedUtils; +import org.apache.http.entity.ByteArrayEntity; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static feign.Util.UTF_8; + +/*** + * This class is to be used to get HTTP Client from feign library + * TODO: Remove this once the Http Client library is updated + */ +public final class ApacheFeignHttpClient implements Client { + private static final String ACCEPT_HEADER_NAME = "Accept"; + public static final String CHARSET = "UTF-8"; + + private final HttpClient client; + + public ApacheFeignHttpClient() { + this(HttpClientBuilder.create().build()); + } + + public ApacheFeignHttpClient(HttpClient client) { + this.client = client; + } + + @Override + public Response execute(Request request, Request.Options options) throws IOException { + HttpUriRequest httpUriRequest; + try { + httpUriRequest = toHttpUriRequest(request, options); + } catch (URISyntaxException e) { + throw new IOException("URL '" + request.url() + "' couldn't be parsed into a URI", e); + } + HttpResponse httpResponse = client.execute(httpUriRequest); + return toFeignResponse(httpResponse, request); + } + + HttpUriRequest toHttpUriRequest(Request request, Request.Options options) + throws URISyntaxException { + RequestBuilder requestBuilder = RequestBuilder.create(request.httpMethod().name()); + + // per request timeouts + RequestConfig requestConfig = + (client instanceof Configurable ? RequestConfig.copy(((Configurable) client).getConfig()) + : RequestConfig.custom()) + .setConnectTimeout(options.connectTimeoutMillis()) + .setSocketTimeout(options.readTimeoutMillis()) + .build(); + requestBuilder.setConfig(requestConfig); + + URI uri = new URIBuilder(request.url()).build(); + + requestBuilder.setUri(uri.getScheme() + "://" + uri.getAuthority() + uri.getRawPath()); + + // request query params + List queryParams = + URLEncodedUtils.parse(uri,CHARSET); + for (NameValuePair queryParam : queryParams) { + requestBuilder.addParameter(queryParam); + } + + // request headers + boolean hasAcceptHeader = false; + for (Map.Entry> headerEntry : request.headers().entrySet()) { + String headerName = headerEntry.getKey(); + if (headerName.equalsIgnoreCase(ACCEPT_HEADER_NAME)) { + hasAcceptHeader = true; + } + + if (headerName.equalsIgnoreCase(Util.CONTENT_LENGTH)) { + // The 'Content-Length' header is always set by the Apache client and it + // doesn't like us to set it as well. + continue; + } + + for (String headerValue : headerEntry.getValue()) { + requestBuilder.addHeader(headerName, headerValue); + } + } + // some servers choke on the default accept string, so we'll set it to anything + if (!hasAcceptHeader) { + requestBuilder.addHeader(ACCEPT_HEADER_NAME, "*/*"); + } + + // request body + if (request.body() != null) { + HttpEntity entity = null; + if (request.charset() != null) { + ContentType contentType = getContentType(request); + String content = new String(request.body(), request.charset()); + entity = new StringEntity(content, contentType); + } else { + entity = new ByteArrayEntity(request.body()); + } + + requestBuilder.setEntity(entity); + } else { + requestBuilder.setEntity(new ByteArrayEntity(new byte[0])); + } + + return requestBuilder.build(); + } + + private ContentType getContentType(Request request) { + ContentType contentType = null; + for (Map.Entry> entry : request.headers().entrySet()) + if (entry.getKey().equalsIgnoreCase("Content-Type")) { + Collection values = entry.getValue(); + if (values != null && !values.isEmpty()) { + contentType = ContentType.parse(values.iterator().next()); + if (contentType.getCharset() == null) { + contentType = contentType.withCharset(request.charset()); + } + break; + } + } + return contentType; + } + + Response toFeignResponse(HttpResponse httpResponse, Request request) throws IOException { + StatusLine statusLine = httpResponse.getStatusLine(); + int statusCode = statusLine.getStatusCode(); + + String reason = statusLine.getReasonPhrase(); + + Map> headers = new HashMap>(); + for (Header header : httpResponse.getAllHeaders()) { + String name = header.getName(); + String value = header.getValue(); + + Collection headerValues = headers.get(name); + if (headerValues == null) { + headerValues = new ArrayList(); + headers.put(name, headerValues); + } + headerValues.add(value); + } + + return Response.builder() + .status(statusCode) + .reason(reason) + .headers(headers) + .request(request) + .body(toFeignBody(httpResponse)) + .build(); + } + + Response.Body toFeignBody(HttpResponse httpResponse) { + final HttpEntity entity = httpResponse.getEntity(); + if (entity == null) { + return null; + } + return new Response.Body() { + + @Override + public Integer length() { + return entity.getContentLength() >= 0 && entity.getContentLength() <= Integer.MAX_VALUE + ? (int) entity.getContentLength() + : null; + } + + @Override + public boolean isRepeatable() { + return entity.isRepeatable(); + } + + @Override + public InputStream asInputStream() throws IOException { + return entity.getContent(); + } + + @SuppressWarnings("deprecation") + @Override + public Reader asReader() throws IOException { + return new InputStreamReader(asInputStream(), UTF_8); + } + + @Override + public Reader asReader(Charset charset) throws IOException { + Util.checkNotNull(charset, "charset should not be null"); + return new InputStreamReader(asInputStream(), charset); + } + + @Override + public void close() throws IOException { + EntityUtils.consume(entity); + } + }; + } +} \ No newline at end of file diff --git a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/util/FilterUtils.java b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/util/FilterUtils.java index 14db15b6d..1c768c3f1 100644 --- a/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/util/FilterUtils.java +++ b/gateway/enforcer/org.wso2.apk.enforcer/src/main/java/org/wso2/apk/enforcer/util/FilterUtils.java @@ -31,7 +31,6 @@ import org.apache.http.conn.ssl.SSLContextBuilder; import org.apache.http.conn.ssl.SSLContexts; import org.apache.http.conn.ssl.SSLSocketFactory; -import org.apache.http.conn.ssl.X509HostnameVerifier; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.logging.log4j.LogManager; @@ -72,9 +71,10 @@ import java.util.List; import java.util.Map; import java.util.UUID; - +import javax.net.ssl.HostnameVerifier; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; /** * Common set of utility methods used by the filter core component. @@ -103,9 +103,18 @@ public static String getMaskedToken(String token) { * @return HTTP client */ public static HttpClient getHttpClient(String protocol) { + return getHttpClient(null, null, null); } + public static HttpClient getMutualSSLHttpClient(String protocol, List hostnames) { + + Map options = new HashMap<>(); + options.put("HOSTNAMES", hostnames); + return getHttpClient(ConfigHolder.getInstance().getKeyStore(), ConfigHolder.getInstance().getTrustStore(), + options); + } + /** * Return a http client instance. * @@ -113,13 +122,11 @@ public static HttpClient getHttpClient(String protocol) { * @param options - HTTP client options * @return HTTP client */ - public static HttpClient getHttpClient(KeyStore clientKeyStore, KeyStore clientTrustStore, Map options) { - - // APIManagerConfiguration configuration = ServiceReferenceHolder.getInstance(). - // getAPIManagerConfigurationService().getAPIManagerConfiguration(); + public static HttpClient getHttpClient(KeyStore clientKeyStore, KeyStore clientTrustStore, + Map options) { - String maxTotal = "100"; //TODO : Read from config - String defaultMaxPerRoute = "10"; //TODO : Read from config + int maxTotal = 100; //TODO : Read from config + int defaultMaxPerRoute = 10; //TODO : Read from config if (options == null) { options = Collections.emptyMap(); @@ -127,27 +134,27 @@ public static HttpClient getHttpClient(KeyStore clientKeyStore, KeyStore clientT PoolingHttpClientConnectionManager pool = null; try { - pool = getPoolingHttpClientConnectionManager(clientKeyStore, clientTrustStore); - pool.setMaxTotal(Integer.parseInt(options.getOrDefault(HTTPClientOptions.MAX_OPEN_CONNECTIONS, - maxTotal))); - pool.setDefaultMaxPerRoute(Integer.parseInt(options.getOrDefault(HTTPClientOptions.MAX_PER_ROUTE, - defaultMaxPerRoute))); + pool = getPoolingHttpClientConnectionManager(clientKeyStore, clientTrustStore, options); + pool.setMaxTotal((Integer) options.getOrDefault(HTTPClientOptions.MAX_OPEN_CONNECTIONS, maxTotal)); + pool.setDefaultMaxPerRoute((Integer) options.getOrDefault(HTTPClientOptions.MAX_PER_ROUTE, + defaultMaxPerRoute)); } catch (EnforcerException e) { log.error("Error while getting http client connection manager", e); } RequestConfig.Builder pramsBuilder = RequestConfig.custom(); if (options.containsKey(HTTPClientOptions.CONNECT_TIMEOUT)) { - pramsBuilder.setConnectTimeout(Integer.parseInt(options.get(HTTPClientOptions.CONNECT_TIMEOUT))); + pramsBuilder.setConnectTimeout((Integer) options.get(HTTPClientOptions.CONNECT_TIMEOUT)); } if (options.containsKey(HTTPClientOptions.SOCKET_TIMEOUT)) { - pramsBuilder.setSocketTimeout(Integer.parseInt(options.get(HTTPClientOptions.SOCKET_TIMEOUT))); + pramsBuilder.setSocketTimeout((Integer) options.get(HTTPClientOptions.SOCKET_TIMEOUT)); } RequestConfig params = pramsBuilder.build(); return HttpClients.custom().setConnectionManager(pool).setDefaultRequestConfig(params).build(); } public static KeyStore createClientKeyStore(String certPath, String keyPath) { + try { Certificate cert = TLSUtils.getCertificateFromFile(certPath); Key key = JWTUtils.getPrivateKey(keyPath); @@ -157,8 +164,8 @@ public static KeyStore createClientKeyStore(String certPath, String keyPath) { KeyManagerFactory keyMgrFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyMgrFactory.init(opaKeyStore, null); return opaKeyStore; - } catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | EnforcerException - | UnrecoverableKeyException e) { + } catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | EnforcerException | + UnrecoverableKeyException e) { log.error("Error creating client KeyStore by loading cert and key from file", ErrorDetails.errorLog(LoggingConstants.Severity.MAJOR, 7100), e); return null; @@ -170,20 +177,21 @@ public static KeyStore createClientKeyStore(String certPath, String keyPath) { * * @return PoolManager */ - private static PoolingHttpClientConnectionManager getPoolingHttpClientConnectionManager( - KeyStore clientKeyStore, KeyStore clientTrustStore) throws EnforcerException { - - SSLConnectionSocketFactory socketFactory = createSocketFactory(clientKeyStore, clientTrustStore); - org.apache.http.config.Registry socketFactoryRegistry = - RegistryBuilder.create() - .register(APIConstants.HTTP_PROTOCOL, PlainConnectionSocketFactory.getSocketFactory()) - .register(APIConstants.HTTPS_PROTOCOL, socketFactory) - .build(); + private static PoolingHttpClientConnectionManager getPoolingHttpClientConnectionManager(KeyStore clientKeyStore, + KeyStore clientTrustStore + , Map options) throws EnforcerException { + + SSLConnectionSocketFactory socketFactory = createSocketFactory(clientKeyStore, clientTrustStore, options); + org.apache.http.config.Registry socketFactoryRegistry = + RegistryBuilder.create().register(APIConstants.HTTP_PROTOCOL, + PlainConnectionSocketFactory.getSocketFactory()).register(APIConstants.HTTPS_PROTOCOL, + socketFactory).build(); return new PoolingHttpClientConnectionManager(socketFactoryRegistry); } - private static SSLConnectionSocketFactory createSocketFactory(KeyStore clientKeyStore, KeyStore clientTrustStore) - throws EnforcerException { + private static SSLConnectionSocketFactory createSocketFactory(KeyStore clientKeyStore, KeyStore clientTrustStore, + Map options) throws EnforcerException { + SSLContext sslContext; try { KeyStore trustStore = ConfigHolder.getInstance().getTrustStore(); @@ -196,9 +204,22 @@ private static SSLConnectionSocketFactory createSocketFactory(KeyStore clientKey } sslContext = sslContextBuilder.build(); - X509HostnameVerifier hostnameVerifier; + HostnameVerifier hostnameVerifier; String hostnameVerifierOption = System.getProperty(HOST_NAME_VERIFIER); - + Object hostnames = options.get("HOSTNAMES"); + if (hostnames instanceof List) { + hostnameVerifier = new HostnameVerifier() { + + @Override + public boolean verify(String hostname, SSLSession session) { + + if (hostnames != null && ((List) hostnames).contains(hostname)) { + return true; + } + return false; + } + }; + } if (ALLOW_ALL.equalsIgnoreCase(hostnameVerifierOption)) { hostnameVerifier = SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER; } else if (STRICT.equalsIgnoreCase(hostnameVerifierOption)) { @@ -224,6 +245,7 @@ public static void handleException(String msg, Throwable t) throws EnforcerExcep } public static String getTenantDomainFromRequestURL(String requestURI) { + String domain = null; if (requestURI.contains("/t/")) { int index = requestURI.indexOf("/t/"); @@ -235,6 +257,7 @@ public static String getTenantDomainFromRequestURL(String requestURI) { } public static AuthenticationContext generateAuthenticationContextForUnsecured(RequestContext requestContext) { + AuthenticationContext authContext = requestContext.getAuthenticationContext(); String clientIP = requestContext.getClientIp(); @@ -263,9 +286,8 @@ public static AuthenticationContext generateAuthenticationContextForUnsecured(Re public static AuthenticationContext generateAuthenticationContext(RequestContext requestContext, String jti, JWTValidationInfo jwtValidationInfo, - APIKeyValidationInfoDTO apiKeyValidationInfoDTO, - String endUserToken, String rawToken, - boolean isOauth) { + APIKeyValidationInfoDTO apiKeyValidationInfoDTO + , String endUserToken, String rawToken, boolean isOauth) { AuthenticationContext authContext = requestContext.getAuthenticationContext(); authContext.setAuthenticated(true); @@ -346,9 +368,8 @@ public static BigInteger ipToBigInteger(String ipAddress) { * @throws java.text.ParseException */ public static AuthenticationContext generateAuthenticationContext(String tokenIdentifier, JWTClaimsSet payload, - JSONObject api, - String apiUUID, String rawToken) - throws java.text.ParseException { + JSONObject api, String apiUUID, + String rawToken) throws java.text.ParseException { AuthenticationContext authContext = new AuthenticationContext(); authContext.setAuthenticated(true); @@ -365,8 +386,7 @@ public static AuthenticationContext generateAuthenticationContext(String tokenId authContext.setApiUUID(apiUUID); } authContext.setApplicationName(APIConstants.JwtTokenConstants.INTERNAL_KEY_APP_NAME); - authContext.setApplicationUUID(UUID.nameUUIDFromBytes(APIConstants.JwtTokenConstants.INTERNAL_KEY_APP_NAME. - getBytes(StandardCharsets.UTF_8)).toString()); + authContext.setApplicationUUID(UUID.nameUUIDFromBytes(APIConstants.JwtTokenConstants.INTERNAL_KEY_APP_NAME.getBytes(StandardCharsets.UTF_8)).toString()); authContext.setApplicationTier(APIConstants.UNLIMITED_TIER); authContext.setSubscriber(APIConstants.JwtTokenConstants.INTERNAL_KEY_APP_NAME); return authContext; @@ -386,8 +406,8 @@ public static JWTInfoDto generateJWTInfoDto(JSONObject subscribedAPI, JWTValidat return jwtInfoDto; } - private static void constructJWTContent(JSONObject subscribedAPI, - APIKeyValidationInfoDTO apiKeyValidationInfoDTO, JWTInfoDto jwtInfoDto) { + private static void constructJWTContent(JSONObject subscribedAPI, APIKeyValidationInfoDTO apiKeyValidationInfoDTO + , JWTInfoDto jwtInfoDto) { Map claims = getClaimsFromJWTValidationInfo(jwtInfoDto); if (claims != null) { @@ -419,20 +439,15 @@ private static void constructJWTContent(JSONObject subscribedAPI, String apiName = subscribedAPI.getAsString(JwtConstants.API_NAME); jwtInfoDto.setApiName(apiName); String subscriptionTier = subscribedAPI.getAsString(JwtConstants.SUBSCRIPTION_TIER); - String subscriptionTenantDomain = - subscribedAPI.getAsString(JwtConstants.SUBSCRIBER_TENANT_DOMAIN); + String subscriptionTenantDomain = subscribedAPI.getAsString(JwtConstants.SUBSCRIBER_TENANT_DOMAIN); jwtInfoDto.setSubscriptionTier(subscriptionTier); jwtInfoDto.setEndUserTenantId(0); if (claims != null && claims.get(JwtConstants.APPLICATION) != null) { - JSONObject - applicationObj = (JSONObject) claims.get(JwtConstants.APPLICATION); - jwtInfoDto.setApplicationId( - String.valueOf(applicationObj.getAsNumber(JwtConstants.APPLICATION_ID))); - jwtInfoDto - .setApplicationName(applicationObj.getAsString(JwtConstants.APPLICATION_NAME)); - jwtInfoDto - .setApplicationTier(applicationObj.getAsString(JwtConstants.APPLICATION_TIER)); + JSONObject applicationObj = (JSONObject) claims.get(JwtConstants.APPLICATION); + jwtInfoDto.setApplicationId(String.valueOf(applicationObj.getAsNumber(JwtConstants.APPLICATION_ID))); + jwtInfoDto.setApplicationName(applicationObj.getAsString(JwtConstants.APPLICATION_NAME)); + jwtInfoDto.setApplicationTier(applicationObj.getAsString(JwtConstants.APPLICATION_TIER)); jwtInfoDto.setSubscriber(applicationObj.getAsString(JwtConstants.APPLICATION_OWNER)); } } @@ -455,6 +470,7 @@ private static Map getClaimsFromJWTValidationInfo(JWTInfoDto jwt * @param e - APISecurityException thrown when validation failure happens at filter level. */ public static void setErrorToContext(RequestContext requestContext, APISecurityException e) { + Map requestContextProperties = requestContext.getProperties(); if (!requestContextProperties.containsKey(APIConstants.MessageFormat.STATUS_CODE)) { requestContext.getProperties().put(APIConstants.MessageFormat.STATUS_CODE, e.getStatusCode()); @@ -483,6 +499,7 @@ public static void setErrorToContext(RequestContext requestContext, APISecurityE */ public static void setErrorToContext(RequestContext context, int errorCode, int statusCode, String message, String desc) { + Map properties = context.getProperties(); properties.putIfAbsent(APIConstants.MessageFormat.STATUS_CODE, statusCode); properties.putIfAbsent(APIConstants.MessageFormat.ERROR_CODE, String.valueOf(errorCode)); @@ -499,12 +516,13 @@ public static void setErrorToContext(RequestContext context, int errorCode, int * @param requestContext - The context object holds details about the specific request. */ public static void setUnauthenticatedErrorToContext(RequestContext requestContext) { - requestContext.getProperties() - .put(APIConstants.MessageFormat.STATUS_CODE, APIConstants.StatusCodes.UNAUTHENTICATED.getCode()); - requestContext.getProperties() - .put(APIConstants.MessageFormat.ERROR_CODE, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS); - requestContext.getProperties().put(APIConstants.MessageFormat.ERROR_MESSAGE, APISecurityConstants - .getAuthenticationFailureMessage(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS)); + + requestContext.getProperties().put(APIConstants.MessageFormat.STATUS_CODE, + APIConstants.StatusCodes.UNAUTHENTICATED.getCode()); + requestContext.getProperties().put(APIConstants.MessageFormat.ERROR_CODE, + APISecurityConstants.API_AUTH_INVALID_CREDENTIALS); + requestContext.getProperties().put(APIConstants.MessageFormat.ERROR_MESSAGE, + APISecurityConstants.getAuthenticationFailureMessage(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS)); requestContext.getProperties().put(APIConstants.MessageFormat.ERROR_DESCRIPTION, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_DESCRIPTION); } @@ -518,6 +536,7 @@ public static void setUnauthenticatedErrorToContext(RequestContext requestContex * @return A map of type {@code } */ public static Map generateMap(Collection list) { + if (list == null) { return new HashMap<>(); } @@ -537,6 +556,7 @@ public static Map generateMap(Collection list) { * @return tenant domain appended username */ public static String buildUsernameWithTenant(String username, String tenantDomain) { + if (StringUtils.isEmpty(tenantDomain)) { tenantDomain = APIConstants.SUPER_TENANT_DOMAIN_NAME; } @@ -549,6 +569,7 @@ public static String buildUsernameWithTenant(String username, String tenantDomai } public static String getClientIp(Map headers, String knownIp) { + String clientIp = knownIp; String xForwardFor = headers.get(APIConstants.X_FORWARDED_FOR); if (!StringUtils.isEmpty(xForwardFor)) { @@ -563,6 +584,7 @@ public static String getClientIp(Map headers, String knownIp) { } public static String getCertificateHeaderName() { + MutualSSLDto mtlsInfo = ConfigHolder.getInstance().getConfig().getMtlsInfo(); String certificateHeaderName = mtlsInfo.getCertificateHeader(); if (StringUtils.isEmpty(certificateHeaderName)) { @@ -578,6 +600,7 @@ public static String getCertificateHeaderName() { * @return whether the fault scenario should be skipped from publishing to analytics server. */ public static boolean isSkippedAnalyticsFaultEvent(String errorCode) { + return SKIPPED_FAULT_CODES.contains(errorCode); } @@ -587,6 +610,7 @@ public static long getTimeStampSkewInSeconds() { } public static void putToMapIfNotNull(Map map, K key, V value) { + if (value != null) { map.put(key, value); } @@ -597,6 +621,7 @@ public static void putToMapIfNotNull(Map map, K key, V value) { * getHttpClient} */ public static class HTTPClientOptions { + public static final String CONNECT_TIMEOUT = "CONNECT_TIMEOUT"; public static final String SOCKET_TIMEOUT = "SOCKET_TIMEOUT"; public static final String MAX_OPEN_CONNECTIONS = "MAX_OPEN_CONNECTIONS"; diff --git a/helm-charts/templates/data-plane/gateway-components/gateway-runtime/gateway-runtime-deployment.yaml b/helm-charts/templates/data-plane/gateway-components/gateway-runtime/gateway-runtime-deployment.yaml index c7ca9f256..0426ebc38 100644 --- a/helm-charts/templates/data-plane/gateway-components/gateway-runtime/gateway-runtime-deployment.yaml +++ b/helm-charts/templates/data-plane/gateway-components/gateway-runtime/gateway-runtime-deployment.yaml @@ -44,6 +44,14 @@ spec: - name: ADAPTER_XDS_PORT value : "18000" command: ['sh', '-c', 'echo -e "Checking for the availability of Adapter deployment"; while ! nc -z $ADAPTER_HOST $ADAPTER_XDS_PORT; do sleep 1; printf "-"; done; echo -e " >> Adapter has started";'] + - name: check-common-controller + image: busybox:1.32 + env: + - name: COMMON_CONTROLLER_HOST_NAME + value: {{ template "apk-helm.resource.prefix" . }}-common-controller-service.{{ .Release.Namespace }}.svc + - name: COMMON_CONTROLLER_XDS_PORT + value: "18002" + command: ['sh', '-c', 'echo -e "Checking for the availability of common-controller deployment"; while ! nc -z $COMMON_CONTROLLER_HOST_NAME $COMMON_CONTROLLER_XDS_PORT; do sleep 1; printf "-"; done; echo -e " >> common-controller has started";'] securityContext: allowPrivilegeEscalation: false capabilities: @@ -88,6 +96,8 @@ spec: value : "18000" - name: COMMON_CONTROLLER_XDS_PORT value : "18002" + - name: COMMON_CONTROLLER_REST_PORT + value : "18003" - name: ENFORCER_LABEL value : default - name: ENFORCER_REGION