Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

services and servlets #1

Merged
merged 1 commit into from
Sep 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.ttn.demo.core.services;

import com.google.gson.JsonObject;

/**
* The interface Search image service.
*/
public interface SearchImageService {
/**
* Gets image.
*
* @return the image
*/
public JsonObject getImage();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.ttn.demo.core.services.impl;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ttn.demo.core.services.SearchImageService;

/**
* The type Search dog image service.
*/
@Component(service = SearchImageService.class, property = {"type=dog"})
public class SearchDogImageServiceImpl implements SearchImageService {

private static final Logger LOGGER = LoggerFactory.getLogger(SearchDogImageServiceImpl.class);

@Override
public JsonObject getImage() {
HttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet("https://dog.ceo/api/breeds/image/random");

try {
HttpResponse response = httpClient.execute(httpGet);
if (response.getStatusLine().getStatusCode() == 200) {
String jsonResponse = EntityUtils.toString(response.getEntity());
JsonObject jsonObject = JsonParser.parseString(jsonResponse).getAsJsonObject();

LOGGER.info("API Response: " + jsonObject.toString());

return jsonObject;
}
} catch (Exception e) {
LOGGER.error("Error while fetching API data: " + e.getMessage(), e);
}

return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.ttn.demo.core.services.impl;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ttn.demo.core.services.SearchImageService;

/**
* The type Search fox image service.
*/
@Component(service = SearchImageService.class, property = {"type=fox"})
public class SearchFoxImageServiceImpl implements SearchImageService {

private static final Logger LOGGER = LoggerFactory.getLogger(SearchFoxImageServiceImpl.class);

@Override
public JsonObject getImage() {
HttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet("https://randomfox.ca/floof/");

try {
HttpResponse response = httpClient.execute(httpGet);
if (response.getStatusLine().getStatusCode() == 200) {
String jsonResponse = EntityUtils.toString(response.getEntity());
JsonObject jsonObject = JsonParser.parseString(jsonResponse).getAsJsonObject();

LOGGER.info("Fox API Response: " + jsonObject.toString());

return jsonObject;
} else {
LOGGER.error("Fox API Error - Status Code: " + response.getStatusLine().getStatusCode());
}
} catch (Exception e) {
LOGGER.error("Error while fetching Fox API data: " + e.getMessage(), e);
}

return null;
}
}
148 changes: 148 additions & 0 deletions core/src/main/java/com/ttn/demo/core/servlets/SearchImageServlet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package com.ttn.demo.core.servlets;

import com.google.gson.JsonObject;
import com.ttn.demo.core.services.SearchImageService;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.servlet.Servlet;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
* The type Search image servlet.
*/
@Component(
service = Servlet.class,
property = {
"sling.servlet.paths=/bin/searchimage",
"sling.servlet.methods=GET"
}
)
public class SearchImageServlet extends SlingSafeMethodsServlet {

private static final Logger LOGGER = LoggerFactory.getLogger(SearchImageServlet.class);

private final Map<String, SearchImageService> serviceMap = new HashMap<>();

@Reference(
service = SearchImageService.class,
cardinality = ReferenceCardinality.MULTIPLE,
policy = ReferencePolicy.DYNAMIC,
bind = "bindService",
unbind = "unbindService"
)

/*
- By marking the field as volatile, you tell the Java Virtual Machine (JVM) to always read the reference directly from memory,
ensuring that you get the most up-to-date reference, especially when services are dynamically added or removed.

- Without volatile, there is a risk that a thread may continue using a cached reference to a service even
after the service has been unbound and rebound with a new implementation. This can lead to unexpected behavior.
*/
private volatile SearchImageService[] services;

/**
* Bind service.
*
* @param service the service
* @param properties the properties
*/
protected void bindService(SearchImageService service, Map<String, Object> properties) {
String type = (String) properties.get("type");
if (type != null) {
serviceMap.put(type, service);
}
}

/**
* Unbind service.
*
* @param service the service
* @param properties the properties
*/
protected void unbindService(SearchImageService service, Map<String, Object> properties) {
String type = (String) properties.get("type");
if (type != null) {
serviceMap.remove(type);
}
}

@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
String type = request.getParameter("type");

if (type != null) {
try {
SearchImageService searchImageService = serviceMap.get(type);

if (searchImageService != null) {
JsonObject result = searchImageService.getImage();

if (result != null) {
String imageUrl;

if (result.has("message")) {
imageUrl = result.get("message").getAsString();
} else if (result.has("image")) {
imageUrl = result.get("image").getAsString();
} else {
imageUrl = null; // Neither "message" nor "image" property found
}

if (imageUrl != null) {
// Set the content type to image/jpeg (or the appropriate image format)
response.setContentType("image/jpeg");

// Fetch and stream the image content directly to the response
byte[] imageBytes = loadImageContent(imageUrl);
if (imageBytes != null) {
response.getOutputStream().write(imageBytes);
LOGGER.info("Image rendered successfully.");
return;
}
}
}
}
} catch (Exception e) {
LOGGER.error("Error while processing the request: " + e.getMessage(), e);
}
}

response.setStatus(SlingHttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.getWriter().write("Error occurred while processing the request.");
}

private byte[] loadImageContent(String imageUrl) {
HttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(imageUrl);

try {
HttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();

if (entity != null) {
return EntityUtils.toByteArray(entity);
}
} catch (Exception e) {
LOGGER.error("Error while fetching image content: " + e.getMessage(), e);
}

return null;
}
}