You can find all the Out of the box OSGi configurations at - http://<host>:<port>/system/console/configMgr. Apart from out of the box configurations, we can also create our custom configurations. In this post, we will be creating a custom out of the box configuration which reads the user input and gets the JSON response from a web service.
Code in Action
- To make a custom OSGi configuration, we need to first create an interface whose public methods will represent the fields in the configuration.
- Create an interface named HttpConfiguration and paste the following code in it.
package org.redquark.demo.core.services;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.AttributeType;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.osgi.service.metatype.annotations.Option;
/**
 * @author Anirudh Sharma
 * 
 * This interface represents an OSGi configuration which can be found at - 
 * ./system/console/configMgr
 */
@ObjectClassDefinition(
 name = "Http Configuration",
 description = "This configuration reads the values to make an HTTP call to a JSON webservice")
public @interface HttpConfiguration {
 /**
  * This is a checkbox property which will indicate of the configuration is
  * executed or not
  * 
  * @return {@link Boolean}
  */
 @AttributeDefinition(
  name = "Enable config",
  description = "This property indicates whether the configuration values will taken into account or not",
  type = AttributeType.BOOLEAN)
 public boolean enableConfig();
 /**
  * This method returns the protocol that is being used
  * 
  * @return Protocol
  */
 @AttributeDefinition(
  name = "Protocol",
  description = "Choose Protocol",
  options = {
   @Option(label = "HTTP", value = "http"),
   @Option(label = "HTTPS", value = "https")
  })
 public String getProtocol();
 /**
  * Returns the server
  * 
  * @return {@link String}
  */
 @AttributeDefinition(
  name = "Server",
  description = "Enter the server name")
 public String getServer();
 /**
  * Returns the endpoint
  * 
  * @return {@link String}
  */
 @AttributeDefinition(
  name = "Endpoint",
  description = "Enter the endpoint")
 public String getEndpoint();
}
- This configuration has a checkbox Enable Config, a drop-down Protocol, two text fields Server, and Endpoint.
- Now create an interface HttpService to make the http call as below
package org.redquark.demo.core.services;
/**
 * @author Anirudh Sharma
 * 
 * This interface exposes the functionality of calling a JSON Web Service
 */
public interface HttpService {
 /**
  * This method makes the HTTP call on the given URL
  * 
  * @param url
  * @return {@link String}
  */
 public String makeHttpCall();
}
- Create an implementation class HttpServiceImpl as below.
package org.redquark.demo.core.services.impl;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.metatype.annotations.Designate;
import org.redquark.demo.core.services.HttpConfiguration;
import org.redquark.demo.core.services.HttpService;
import org.redquark.demo.core.utils.Network;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * @author Anirudh Sharma
 * 
 * Implementation class of HttpService interface and this class reads values from the OSGi configuration as well
 */
@Component(service = HttpService.class, immediate = true)
@Designate(ocd = HttpConfiguration.class)
public class HttpServiceImpl implements HttpService {
 /**
  * Logger
  */
 private static final Logger log = LoggerFactory.getLogger(HttpServiceImpl.class);
 /**
  * Instance of the OSGi configuration class
  */
 private HttpConfiguration configuration;
 @Activate
 protected void activate(HttpConfiguration configuration) {
  this.configuration = configuration;
 }
 /**
  * Overridden method of the HttpService
  */
 @Override
 public String makeHttpCall() {
  log.info("----------< Reading the config values >----------");
  try {
   /**
    * Reading values from the configuration
    */
   boolean enable = configuration.enableConfig();
   String protocol = configuration.getProtocol();
   String server = configuration.getServer();
   String endpoint = configuration.getEndpoint();
   /**
    * Constructing the URL
    */
   String url = protocol + "://" + server + "/" + endpoint;
   /**
    * Make HTTP call only if "enable" is true
    */
   if (enable) {
    /**
     * Making the actual HTTP call
     */
    String response = Network.readJson(url);
    /**
     * Printing the response in the logs
     */
    log.info("----------< JSON response from the webservice is >----------");
    log.info(response);
    return response;
   } else {
    log.info("----------< Configuration is not enabled >----------");
    return "Configuration not enabled";
   }
  } catch (Exception e) {
   log.error(e.getMessage(), e);
   return "Error occurred" + e.getMessage();
  }
 }
}
- This is an OSGi component in which we are reading values from the OSGi configuration. Notice that we are using @Designate annotation to link this class to the configuration.
- Now create a simple Sling Servlet to use this component as follows.
package org.redquark.demo.core.servlets;
import javax.servlet.Servlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.HttpConstants;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.redquark.demo.core.services.HttpService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * @author Anirudh Sharma
 * 
 * This method makes an HTTP call and read the value from the JSON webservice via an OSGi configuration
 *
 */
@Component(service = Servlet.class, property = {
 Constants.SERVICE_DESCRIPTION + "=HTTP servlet",
 "sling.servlet.methods=" + HttpConstants.METHOD_GET,
 "sling.servlet.paths=" + "/bin/demo/httpcall"
})
public class HttpServlet extends SlingSafeMethodsServlet {
 /**
  * Generated serialVersionUid
  */
 private static final long serialVersionUID = -2014397651676211439 L;
 /**
  * Logger
  */
 private static final Logger log = LoggerFactory.getLogger(HttpServlet.class);
 @Reference
 private HttpService httpService;
 /**
  * Overridden doGet() method
  */
 @Override
 protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) {
  try {
   String jsonResponse = httpService.makeHttpCall();
   /**
    * Printing the json response on the browser
    */
   response.getWriter().println(jsonResponse);
  } catch (Exception e) {
   log.error(e.getMessage(), e);
  }
 }
}
- Go to the ./system/console/configMgr and search for Http Configuration and open it and configure it accordingly. Then save.
|  | 
| OSGi Configuration | 
- Now hit the request - http://<host>:<port>/bin/demo/httpcall and you will get the JSON response as follows
[{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}, {"userId": 1, "id": 2, "title": "quis ut nam facilis et officia qui", "completed": false}, {"userId": 1, "id": 3, "title": "fugiat veniam minus", "completed": false}, {"userId": 1, "id": 4, "title": "et porro tempora", "completed": true}, ...]
 
No comments:
Post a Comment
If you have any doubts or questions, please let us know.