Chapter 5. Preparing an API service for 3scale discovery Red Hat 3scale API Management is an offering from Red Hat that enables you to regulate access to API services on the public Internet. The functionality of 3scale includes the ability to enforce service-level agreements (SLAs), manage API versions, provide security and authentication services and more. Fuse supports a service discovery feature for 3scale, which makes it easy to discover Fuse services from the 3scale Admin Portal UI. Using service discovery, you can scan for Fuse applications running in the same OpenShift cluster and automatically import the associated API definitions into 3scale. Prerequisites A Fuse application that provides an API service is deployed and running in OpenShift. The Fuse application is annotated with the requisite annotations to make it discoverable by 3scale. Note Fuse projects that are generated by API Designer are pre-configured to automatically provide the requisite annotations. For Fuse projects that are not generated by API Designer, you must configure your project as described in Adding annotations for Fuse projects that are not generated by API Designer . The 3scale API Management system is deployed on the same OpenShift cluster as the API service that is to be discovered. For details of the procedure to discover an API service in 3scale, see the service discovery section of the Red Hat 3scale API Management Admin Portal Guide . Additional resources Red Hat 3scale API Management product page Red Hat 3scale API Management documentation 5.1. Adding annotations for Fuse projects that are not generated by API Designer In order for 3scale to discover an API service, the Fuse application that provides the API service must include Kubernetes Service Annotations that make it discoverable. These annotations are provided by the Service Discovery Enricher which is part of the OpenShift Maven Plugin. For Apache Camel Rest DSL projects, the OpenShift Maven Plugin runs the Service Discovery Enricher by default. Fuse projects that are generated by API Designer are pre-configured to automatically provide the required annotations. Procedure For a Fuse Rest DSL project that is not generated by API Designer, configure the project as follows: Edit the Fuse project's pom.xml file to include the openshift-maven-plugin dependency, as shown in this example: <plugin> <groupId>org.jboss.redhat-fuse</groupId> <artifactId>openshift-maven-plugin</artifactId> <version>USD{fuse.version}</version> <executions> <execution> <goals> <goal>resource</goal> <goal>build</goal> </goals> </execution> </executions> </plugin> The OpenShift Maven Plugin runs the Service Discovery Enricher if certain project-level conditions are met (for example, the project must be a Camel Rest DSL project). You do not need to specify the Service Discovery Enricher as a dependency in the pom.xml file, unless you want to customize the enricher's behavior (as described in Customizing the API service annotation values .) In the Fuse Rest DSL project's camel-context.xml file, specify the following attributes in the restConfiguration element: scheme : The scheme part of the URL where the service is hosted. You can specify "http" or "https". contextPath : The path part of the URL where the API service is hosted. apiContextPath : The path to the location where the API service description document is hosted. You can specify either a relative path if the document is self-hosted or a full URL if the document is hosted externally. The following excerpt from an example camel-context.xml file shows annotation attribute values in the restConfiguration element: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <camelContext xmlns="http://camel.apache.org/schema/spring"> <restConfiguration component="servlet" scheme="https" contextPath="myapi" apiContextPath="myapi/openapi.json"/> ... The enricher uses the information provided by these restConfiguration element attribute values to create values for the discovery.3scale.net/scheme , discovery.3scale.net/path , and the discovery.3scale.net/description-path annotations, thereby making the project's deployed OpenShift service discoverable by 3scale as described in the see the service discovery section of the Red Hat 3scale API Management Admin Portal Guide . The enricher adds the following label and annotations to make the service discoverable by 3scale: The discovery.3scale.net label: By default, the enricher sets this value to "true". 3scale uses this label when it executes the selector definition to find all services that need discovery. The following annotations: discovery.3scale.net/discovery-version : (optional) The version of the 3scale discovery process. The enricher sets this value to "v1" by default. discovery.3scale.net/scheme : The scheme part of the URL where the service is hosted. The enricher uses the default "http" unless you override it in the restConfiguration element's scheme attribute. The other possible value is "https". discovery.3scale.net/path : The path part of the URL where the service is hosted. This annotation is omitted when the path is at root, "/". The enricher gets this value from the restConfiguration element's path attribute. discovery.3scale.net/port : The port of the service. The enricher obtains this value from the Kubernetes service definition, which contains the the port numbers of the services it exposes. If the Kubernetes service definition exposes more than one service, the enricher uses the first port listed. discovery.3scale.net/description-path : (optional) The path to the OpenAPI service description document. The enricher gets this value from the restConfiguration element's contextPath attribute. You can customize the behavior of the Service Discovery Enricher, as described in Customizing the API service annotation values . 5.2. Customizing the API service annotation values The Maven Fabric8 Plugin runs the Fabric8 Service Discovery Enricher by default. The enricher adds annotations to the Fuse Rest DSL project's API service so that the API service is discoverable by 3scale, as described in Using Service Discovery in the Red Hat 3scale API Management Admin Portal Guide guide. The enricher uses default values for some annotations and obtains values for other annotations from the project's camel-context.xml file. You can override the default values and the values defined in the camel-context.xml file by defining values in the Fuse project pom.xml file or in a service.yml file. (If you define values in both files, the enricher uses the values from the service.yml file.) See Fabric8 Service Discovery Enricher elements for a description of the elements that you can specify for the Fabric8 Service Discovery Enricher. Procedure To specify annotation values in the Fuse project pom.xml file: Open your Fuse project's pom.xml file in an editor of your choice. Locate the openshift-maven-plugin dependency, as shown in this example: <plugin> <groupId>org.jboss.redhat-fuse</groupId> <artifactId>openshift-maven-plugin</artifactId> <version>USD{fuse.version}</version> <executions> <execution> <goals> <goal>resource</goal> <goal>build</goal> </goals> </execution> </executions> </plugin> Add the Fabric8 Service Discovery Enricher as a dependency to the openshift-maven plugin as shown in the following example. <plugin> <groupId>org.jboss.redhat-fuse</groupId> <artifactId>openshift-maven-plugin</artifactId> <version>USD{fuse.version}</version> <executions> <execution> <goals> <goal>resource</goal> <goal>build</goal> </goals> </execution> </executions> <dependencies> <dependency> <groupId>io.acme</groupId> <artifactId>myenricher</artifactId> <version>1.0</version> <configuration> <enricher> <config> <f8-service-discovery> <scheme>https</scheme> <path>/api</path> <descriptionPath>/api/openapi.json</descriptionPath> </f8-service-discovery> </config> </enricher> </configuration> </dependency> </dependencies> </plugin> Save your changes. Alternatively, you can use a src/main/fabric8/service.yml fragment to override the annotation values, as shown in the following example: 5.3. Fabric8 Service Discovery Enricher elements The following table describes the elements that you can specify for the Fabric8 Service Discovery Enricher, if you want to override the default values and the values defined in the camel-context.xml file. You can define these values in the Fuse Rest DSL project's pom.xml file or in a src/main/fabric8/service.yml file. (If you define values in both files, the enricher uses the values from the service.yml file.) See Customizing the API service annotation values for examples. Table 5.1. Fabric8 Service Discovery Enricher elements Element Description Default springDir The path to the spring configuration directory that contains the camel-context.xml file. The /src/main/resources/spring path which is used to recognize a Camel Rest DSL project. scheme The scheme part of the URL where the service is hosted. You can specify "http" or "https". http path The path part of the URL where the API service is hosted. port The port part of the URL where the API service is hosted. 80 descriptionPath The path to a location where the API service description document is hosted. You can specify either a relative path if the document is self-hosted or a full URL if the document is hosted externally. discoveryVersion The version of the 3scale discovery implementation. v1 discoverable The element that sets the discovery.3scale.net label to either true or false . If set to true , 3scale will try to discover this service. If set to false , 3scale will not try to discover this service. You can use this element as a switch, to temporary turn off 3scale discovery integration by setting it to "false". If you do not specify a value, the enricher tries to auto-detect whether it can make the service discoverable. If the enricher determines that it cannot make the service discoverable, 3scale will not try to discover this service.

Commands:
<plugin> <groupId>org.jboss.redhat-fuse</groupId> <artifactId>openshift-maven-plugin</artifactId> <version>USD{fuse.version}</version> <executions> <execution> <goals> <goal>resource</goal> <goal>build</goal> </goals> </execution> </executions> </plugin>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <camelContext xmlns="http://camel.apache.org/schema/spring"> <restConfiguration component="servlet" scheme="https" contextPath="myapi" apiContextPath="myapi/openapi.json"/>
<plugin> <groupId>org.jboss.redhat-fuse</groupId> <artifactId>openshift-maven-plugin</artifactId> <version>USD{fuse.version}</version> <executions> <execution> <goals> <goal>resource</goal> <goal>build</goal> </goals> </execution> </executions> </plugin>
<plugin> <groupId>org.jboss.redhat-fuse</groupId> <artifactId>openshift-maven-plugin</artifactId> <version>USD{fuse.version}</version> <executions> <execution> <goals> <goal>resource</goal> <goal>build</goal> </goals> </execution> </executions> <dependencies> <dependency> <groupId>io.acme</groupId> <artifactId>myenricher</artifactId> <version>1.0</version> <configuration> <enricher> <config> <f8-service-discovery> <scheme>https</scheme> <path>/api</path> <descriptionPath>/api/openapi.json</descriptionPath> </f8-service-discovery> </config> </enricher> </configuration> </dependency> </dependencies> </plugin>
kind: Service name: metadata: labels: discovery.3scale.net/discoverable : "true" annotations: discovery.3scale.net/discovery-version : "v1" discovery.3scale.net/scheme : "https" discovery.3scale.net/path : "/api" discovery.3scale.net/port : "443" discovery.3scale.net/description-path : "/api/openapi.json" spec: type: LoadBalancer