Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.
SOLVED

Could not adapt the given Sling Model from neither request nor resource

Avatar

Level 2

I am using AEM 6.5

 

I am trying to build a Translation Connector. I am using the AEM Translation Framework Bootstrap Connector https://github.com/Adobe-Marketing-Cloud/aem-translation-framework-bootstrap-connector

 

I can build and install the bundle to my local AEM instance using mvn clean install -PautoInstallPackage

 

After the bundles are installed I go to "Cloud Services" > "Translation Cloud Services" > "/conf/wknd-events/bootstrap-translation". When I try to create a Bootstrap Connector Configuration I get the following stacktrace. I expect the model to be able to be adapted from the SlingHTTPServletRequest and for the template to render the data.

 

Here is a pastebin with the full stacktrace https://pastebin.com/raw/Fh7CJPqG

This appears to be the most relevant part

 

SightlyException: org.apache.sling.api.SlingException: Cannot get DefaultSlingScript: Identifier com.adobe.granite.translation.connector.bootstrap.ui.models.BootStrapTranslationConnectorModel cannot be correctly instantiated by the Use API

 

java.lang.IllegalStateException: Could not adapt the given Sling Model from neither request nor resource: class com.adobe.granite.translation.connector.bootstrap.ui.models.BootStrapTranslationConnectorModel

 

 

 

Here is the model file

 

 

 

/*
 ADOBE CONFIDENTIAL
 Copyright 2018 Adobe Systems Incorporated
 All Rights Reserved.
 NOTICE:  All information contained herein is, and remains
 the property of Adobe Systems Incorporated and its suppliers,
 if any. The intellectual and technical concepts contained
 herein are proprietary to Adobe Systems Incorporated and its
 suppliers and may be covered by U.S. and Foreign Patents,
 patents in process, and are protected by trade secret or copyright law.
 Dissemination of this information or reproduction of this material
 is strictly forbidden unless prior written permission is obtained
 from Adobe Systems Incorporated.
 */

package com.adobe.granite.translation.connector.bootstrap.ui.models;

import com.adobe.granite.translation.connector.bootstrap.core.BootstrapTranslationCloudConfig;
import com.day.cq.commons.jcr.JcrConstants;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.Self;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.PostConstruct;

/*
 *  Sling Model used in editform.html sightly file for fetching the bootstrap cloud config input fields for populating the form
 *  For more info about Sling Model refer https://sling.apache.org/documentation/bundles/models.html#osgi-service-filters
 */

@Model(adaptables = SlingHttpServletRequest.class)
public class BootStrapTranslationConnectorModel {

    private static final Logger logger = LoggerFactory.getLogger(BootStrapTranslationConnectorModel.class);

    
    private SlingHttpServletRequest request;

    private ResourceResolver resourceResolver;
    private String bootStrapConfigPath;
    private Resource bootStrapConfigResource;

    @PostConstruct
    public void postConstruct() throws Exception {
        bootStrapConfigPath = request.getRequestPathInfo().getSuffix();
        resourceResolver = request.getResourceResolver();
        bootStrapConfigResource = resourceResolver.getResource(bootStrapConfigPath);
    }

    /*
     *  Get the server url for the configuration
     */
    public String getServerUrl() {
        return BootStrapModelUtils.getStringPropertyFromContent(bootStrapConfigResource, BootstrapTranslationCloudConfig.PROPERTY_DUMMY_SERVER_URL, logger);
    }

    public String getServiceId() {
        return BootStrapModelUtils.getStringPropertyFromContent(bootStrapConfigResource, BootstrapTranslationCloudConfig.PROPERTY_DUMMY_CONFIG_ID, logger);
    }

    public String getPreviewDirectory() {
        return BootStrapModelUtils.getStringPropertyFromContent(bootStrapConfigResource, BootstrapTranslationCloudConfig.PROPERTY_PREVIEW_PATH, logger);
    }

    /*
     *  form action attribute (post path where the configuration input values would be saved), jcr:content node of the configuration for bootstrap
     */
    public String getFormPostPath() {
        return bootStrapConfigPath + '/' + JcrConstants.JCR_CONTENT;
    }

}

 

 

 

Here is the HTL template

 

 

 

<sly data-sly-use.config="${'com.adobe.granite.translation.connector.bootstrap.ui.models.BootStrapTranslationConnectorModel'}">

	<!--/* form id should always be services-editor-form, data-foundation-form-ajax and data-foundation-form-loadingmask are used to auto submit the form on save and close  */-->
    <form id="services-editor-form" method="post" action="${config.formPostPath}" class="coral-form coral-Form--vertical foundation-form" data-foundation-form-ajax="true" data-foundation-form-loadingmask="true">

		<!--/* First Load the client library {js, css} both */-->
        <sly data-sly-use.clientlib="/libs/granite/sightly/templates/clientlib.html" />
        <sly data-sly-call="${clientlib.js @ categories='aem.bootstrap.connector'}" />
        <sly data-sly-call="${clientlib.css @ categories='aem.bootstrap.connector'}" />


        <!--/* Title of the Edit form */-->
        <h3 class="form-legend">${'Bootstrap Translation Connector Settings' , locale=request.locale}</h3>

        <!--/* Input field with label and input area */-->
		<label class="fieldlabel">${'Dummy Server URL' , locale=request.locale} </label>
		<input class="inputTextField" type="text" placeholder="${'Use the API/Endpoint URL here' , locale=request.locale}" name="./dummyserverurl" value="${config.serverUrl}" is="coral-textfield" aria-invalid="false">

        <!--/* Input field with label and input area */-->
		<label class="fieldlabel">${'Dummy Service ID' , locale=request.locale} </label>
		<input class="inputTextField bootStrapServerID" type="text" is="coral-textfield" required="true" placeholder="${'Use a customer specific Configuration/Service ID here' , locale=request.locale}" name="./dummyconfigid" value="${config.serviceId}">


        <!--/* Input field with label and input area */-->
		<label class="fieldlabel">${'Target Directory for Preview Content' , locale=request.locale} </label>
		<input class="inputTextField" type="text" is="coral-textfield" placeholder="${'Make sure to enable preview in the Web console for the Bootstrap Translation Factory' , locale=request.locale}" name="./previewPath" value="${config.previewDirectory}">

	</form>

    <!--/* Any button if required, available variants = {"primary", "secondary"} */-->
	<button is="coral-button" class="checkSomeCondition" iconsize="S" variant="primary" >${'Connect' , locale=request.locale} </button>

</sly>

 

 

 

Does anyone have insights into how I can get this working?

 

The full repo that I am working from is here https://github.com/lilt/aem-translation-framework-bootstrap-connector

1 Accepted Solution

Avatar

Correct answer by
Level 2

I was able to get this working.

 

The issue (sadly) was that I was using the wrong branch of the translation framework bootstrap connector repo.

 

The master branch of that repo is set up to work with the AEM Cloud Service SDK.

 

To use the translation framework bootstrap connector with AEM 6.5.0 you need to checkout the aem650 branch https://github.com/Adobe-Marketing-Cloud/aem-translation-framework-bootstrap-connector/tree/aem650

 

Once I was using the aem650 branch everything worked just as expected.

 

I've opened a PR to update this documentation in the repo https://github.com/Adobe-Marketing-Cloud/aem-translation-framework-bootstrap-connector/pull/16

View solution in original post

4 Replies

Avatar

Community Advisor

Hi,

The issue is with the injected service, you need to use either @Deleted Account or @SlingObject to get request object.

 

e.g. https://github.com/arunpatidar02/com.aemlab.junitapp/blob/master/core/src/main/java/com/aemlab/junit/core/models/HelloWorldModel.java

@Model(adaptables = Resource.class)
public class HelloWorldModel {

    @ValueMapValue(name=PROPERTY_RESOURCE_TYPE, injectionStrategy=InjectionStrategy.OPTIONAL)
    @Default(values="No resourceType")
    protected String resourceType;

    @OSGiService
    private SlingSettingsService settings;
    @SlingObject
    private Resource currentResource;
    @SlingObject
    private ResourceResolver resourceResolver;


Arun Patidar

Avatar

Level 2

I am still facing this problem. I get the same stacktrace if I do that. In the code I pasted in the original message the SlingHTTPServletResponse was annotated with \@Self but it didn't show up in the code block for some reason.

 

Here is a link to that file in github where you can see the annotation https://github.com/lilt/aem-translation-framework-bootstrap-connector/blob/master/core/src/main/java...

 

I've also tried using SlingObject instead of Self. The stacktrace is the same in all of these instances. The full stacktrace is posted in the original message.

 

/*
 ADOBE CONFIDENTIAL
 Copyright 2018 Adobe Systems Incorporated
 All Rights Reserved.
 NOTICE:  All information contained herein is, and remains
 the property of Adobe Systems Incorporated and its suppliers,
 if any. The intellectual and technical concepts contained
 herein are proprietary to Adobe Systems Incorporated and its
 suppliers and may be covered by U.S. and Foreign Patents,
 patents in process, and are protected by trade secret or copyright law.
 Dissemination of this information or reproduction of this material
 is strictly forbidden unless prior written permission is obtained
 from Adobe Systems Incorporated.
 */

package com.adobe.granite.translation.connector.bootstrap.ui.models;

import com.adobe.granite.translation.connector.bootstrap.core.BootstrapTranslationCloudConfig;
import com.day.cq.commons.jcr.JcrConstants;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.Self;
import org.apache.sling.models.annotations.injectorspecific.SlingObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.PostConstruct;

/*
 *  Sling Model used in editform.html sightly file for fetching the bootstrap cloud config input fields for populating the form
 *  For more info about Sling Model refer https://sling.apache.org/documentation/bundles/models.html#osgi-service-filters
 */

@Model(adaptables = SlingHttpServletRequest.class)
public class BootStrapTranslationConnectorModel {

    private static final Logger logger = LoggerFactory.getLogger(BootStrapTranslationConnectorModel.class);

    @SlingObject
    private SlingHttpServletRequest request;

    @SlingObject
    private ResourceResolver resourceResolver;
    private String bootStrapConfigPath;
    private Resource bootStrapConfigResource;

    @PostConstruct
    public void postConstruct() throws Exception {
        bootStrapConfigPath = request.getRequestPathInfo().getSuffix();
        resourceResolver = request.getResourceResolver();
        bootStrapConfigResource = resourceResolver.getResource(bootStrapConfigPath);
    }

    /*
     *  Get the server url for the configuration
     */
    public String getServerUrl() {
        return BootStrapModelUtils.getStringPropertyFromContent(bootStrapConfigResource, BootstrapTranslationCloudConfig.PROPERTY_DUMMY_SERVER_URL, logger);
    }

    public String getServiceId() {
        return BootStrapModelUtils.getStringPropertyFromContent(bootStrapConfigResource, BootstrapTranslationCloudConfig.PROPERTY_DUMMY_CONFIG_ID, logger);
    }

    public String getPreviewDirectory() {
        return BootStrapModelUtils.getStringPropertyFromContent(bootStrapConfigResource, BootstrapTranslationCloudConfig.PROPERTY_PREVIEW_PATH, logger);
    }

    /*
     *  form action attribute (post path where the configuration input values would be saved), jcr:content node of the configuration for bootstrap
     */
    public String getFormPostPath() {
        return bootStrapConfigPath + '/' + JcrConstants.JCR_CONTENT;
    }

}

Avatar

Community Advisor

Hi,

I tried with your github code. For me Model works fine.

Though all the methods return null because of suffix is null in my test page.

I can see the componnet with this Model is rendering static content and for one of the method 

public String getFormPostPath() {
        return bootStrapConfigPath + '/' + JcrConstants.JCR_CONTENT;
    }

it return null/jcr:content 



Arun Patidar

Avatar

Correct answer by
Level 2

I was able to get this working.

 

The issue (sadly) was that I was using the wrong branch of the translation framework bootstrap connector repo.

 

The master branch of that repo is set up to work with the AEM Cloud Service SDK.

 

To use the translation framework bootstrap connector with AEM 6.5.0 you need to checkout the aem650 branch https://github.com/Adobe-Marketing-Cloud/aem-translation-framework-bootstrap-connector/tree/aem650

 

Once I was using the aem650 branch everything worked just as expected.

 

I've opened a PR to update this documentation in the repo https://github.com/Adobe-Marketing-Cloud/aem-translation-framework-bootstrap-connector/pull/16