1. Writing OSGi configuration ui.config
ui.config
+> ui.config/src/main/content/jcr_root/apps.flagtick.osgiconfig/config
---> com.flagtick.core.services.impl.FlagtickIntegrationServiceImpl.cfg.json
+> ui.config/src/main/content/jcr_root/apps.flagtick.osgiconfig/config.author
+> ui.config/src/main/content/jcr_root/apps.flagtick.osgiconfig/config.author.dev
+> ui.config/src/main/content/jcr_root/apps.flagtick.osgiconfig/config.author.prod
+> ui.config/src/main/content/jcr_root/apps.flagtick.osgiconfig/config.publish
+> ui.config/src/main/content/jcr_root/apps.flagtick.osgiconfig/config.publish.dev
+> ui.config/src/main/content/jcr_root/apps.flagtick.osgiconfig/config.publish.prod
Note: This is a new <PID>.cfg.json file. The PID is the Persistent Identity of the OSGi component. It is usually the full class name of the OSGi component implementation. Refer format for JSON here.
{
"endPoint": "https://api.flagtick.com",
"apiKey":"$[secret:FLAGTICK_API_KEY]"
}
2. Write service interface Method to DAO (Database)
ui.core
+> ui.core/src/main/java/com.flagtick.core/services/FlagtickIntegrationService.java
+> ui.core/src/main/java/com.flagtick.core/services/impl/FlagtickIntegrationServiceImpl.java
For example:
public interface FlagtickIntegrationService {
LoginResponse login(Map<String, String> paramMap, String fcm_token);
}
/------------------------------------------------------------------------------/
@Component(
immediate = true,
service = FlagtickIntegrationService.class
)
@Designate(ocd = FlagtickIntegrationServiceImpl.Config.class)
public class FlagtickIntegrationServiceImpl implements FlagtickIntegrationService {
private String endPoint;
private String apiKey;
@Activate
protected void activate(Config config) {
endPoint = config.endPoint();
apiKey = config.apiKey();
}
@Override
public LoginResponse login(Map<String, String> paramMap, String fcmToken) {
// TODO
}
@ObjectClassDefinition(
name = "FLAGTICK - Flagtick Service Configurations",
description = "Flagtick Service Configurations"
)
protected @interface Config {
@AttributeDefinition(
name = "Login Endpoint",
description = "URL endpoint for member login into the system",
type = AttributeType.STRING
)
String endPoint();
@AttributeDefinition(
name = "API Key",
description = "API Key",
type = AttributeType.STRING
)
String apiKey();
}
}
3. Writing Servlet to help ajax or Front-end call request.
ui.core
+> ui.core/src/main/java/com.flagtick.core/servlets/LoginServlet.java
We will need to define resourceType with specific METHOD (GET/POST) to mapping action from ui.front-end site.
@Component(immediate = true, service = Servlet.class,
property = {
SERVICE_DESCRIPTION + VerifyUserServlet.SERVLET_SERVICE_DESCRIPTION,
SLING_SERVLET_RESOURCE_TYPES + VerifyUserServlet.RESOURCE_TYPE,
SLING_SERVLET_METHODS + "=" + HttpConstants.METHOD_GET,
SLING_SERVLET_SELECTORS + VerifyUserServlet.SELECTOR,
SLING_SERVLET_EXTENSIONS + "=" + Constants.EXTENSION_JSON
})
public class LoginServlet extends SlingSafeMethodsServlet {
public static final String RESOURCE_TYPE = "=flagtick/components/content/verification-form";
public static final String SELECTOR = "=verify-user";
@Reference
transient private FlagtickIntegrationService flagtickIntegrationService;
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
// TODO
}
}
Note: Resource Type + Selector => generate URL: http://localhost:4502/content/flagtick/us/en/verification/jcr:content/root/container/container/verification_form.verify-user.json?username=flagtick&password=Abc@123456
4. There are many different ways to pass data from AEM to JavaScript.
For example, use LoginFormComponent(login-form.html in ui.apps) to pass value. You can see structure of component in ui.app as below:
+> ui.apps/src/main/content/jcr_root/apps/flagtick/components/content/verification-form/verification-form.html
And there is an example HTL template:
<sly data-sly-use.templates="core/wcm/components/commons/v1/templates.html"
data-sly-use.model="com.flagtick.core.models.FlagtickFormModel">
<div class="flagtick-login"
data-cmp-is="LoginForm"
data-resource="${resource.path}"
data-editmode="${wcmmode.edit ? 'true' : ''}">
<!-- TODO -->
</div>
</sly>
Note: LoginForm => LoginForm.ts or LoginForm.js. Using LoginModal as interface to get/set property from cq:dialog in AEM component.
5. Writing JS function to update code:
private async login(username: string, password: string): Promise<void> {
const resource = this.$component.data('resource') as string;
const editMode = this.$component.data('editmode') as string;
const endpoint = `${resource}.${this.selector}.json?username=${username}&password=${password}`;
if (!editMode) {
await $.get(endpoint) { ... }
}
}