cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to get the code error free

0 Kudos

Hi All,

Let me first mention about what I am trying to acheive:

I am trying to execute an EJB exposed as a webservice from Visual Composer. The EJB will call a BAPI in the backend SAP System through SAP Logon Ticket

What I have done till now:

-I have created a RFC Destination in the J2EE Visual Admin.

-I have coded an EJB that will do a lookup into the JNDI registry and fetch the system details

-Now I need to get the SAP Logon ticket from the Visual composer application which will be a Portal iView later on and pass it on to the EJB via the webservice and connect to the SAP System through JCO and execute the function module

I went through the Forums and found that the code below should work:

HttpServletRequest request = ((IWebContextAdapter) WDWebContextAdapter.getWebContextAdapter()).getHttpServletRequest();

Cookie[] cookies = request.getCookies();

String cookieName = "MYSAPSSO2";//SAPCookie;

for ( int i=0; i<cookies.length; i++) {

Cookie cookie = cookies;

if (cookieName.equals(cookie.getName())){

}

}

IUser user1 = WDClientUser.getCurrentUser().getSAPUser();

String sso = (String)user1.getTransientAttribute(IPrincipal.DEFAULT_NAMESPACE, "MYSAPSSO2_STRING");

The problem that I have is that I am not being able to find the package where I have the IWebContextAdapter and the WDWebContextAdapter. I assume these are Webdnpro classes and I am not sure whether this will work in my context.

I would appreciate if anyone could help me out in this issue!

Best regards,

Sudhi

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Hi All,

there is nothing to be done for the User in this case. Since Suhdi retrieves the JCO connection via JNDI from the destination Service the destination service puts in the current user and its ticket automatically. So the complete code for handling the user is not necessary. The only thing he needs to do is to make sure that he has the SSO enabled in the destination services and that of course SSO is set up between the J2EE and the ABAP System he wants to connect to.

So code looks something like that.

/**

  • Business Method.

*/

public String CreateClient1() {

JCO.Client jcoclient = null;

String S1;

try{

String callerPrincipalName = myContext.getCallerPrincipal().getName();

Context ctx = new InitialContext();

DestinationService dstServ = (DestinationService) ctx.lookup(DestinationService.JNDI_KEY_LOCAL);

if (dstServ == null){

throw new NamingException("Destination Service not available");

} else{

RFCDestination rfc = (RFCDestination) dstServ.getDestination

("RFC","myentry.com");

jcoclient = JCO.createClient(rfc.getJCoProperties());

jcoclient.connect();

// execute BAPI or RFC here

jcoclient.disconnect();

}

}

As explained before. If you set the destination service to SAPAssertion or SAPLogon Ticket all of the user stuff is done for you automatically.

Regards Ingo

Answers (2)

Answers (2)

Former Member
0 Kudos

Hi All,

I guess this is confusing now. What Sudi actually wanted was, to retrieve the SSO Ticket from the header or from somewhere in a WebService which is accessible via SSO Ticket.

The WebDynrpo came in there by accident so maybe to rephrase.

What he wants to accomplish is, that he wants to write an EJB and expose this EJB as WebService. Once this is done, he wants to retrieve the SSO Ticket send by a consuming client to the WebService ( maybe VC ) from somewhere inside the WebService/EJB and then use this ticket in JCO to call an RFC function module/BAPI.

Unfortunately I don't know how this is done but maybe you get a better picture now.

Former Member
0 Kudos

Hi,

IWebContextAdapter, WDWebContextAdapter are placed in DC 'tc/wd/webdynpro' in webdynproservices.jar. So on build time just add reference on 'tc/wd/webdynpro' as used dc of your project.

To force you code work on runtime you should edit application-j2ee-engine.xml file of your ejb project - add reference to tc/wd/webdynpro like:

<reference

reference-type="hard">

<reference-target

provider-name="sap.com"

target-type="service">tc/wd/webdynpro</reference-target>

</reference>

Hope this will help you.

Vlado
Advisor
Advisor
0 Kudos

Hi Sudhi,

Just two corrections to Denis' reply above:

1) Not the "application-j2ee-engine.xml file of your ejb project", but of the web application (Visual Composer, iView?) that the code above is part of.

2) The build time reference is to 'tc/wd/webdynpro' but at runtime its name is just 'webdynpro', i.e.


<reference-target
	provider-name="sap.com"
	target-type="service">tc/wd/webdynpro</reference-target>

Best regards,

Vladimir

0 Kudos

Hi,

First off as Ingo mentioned I am not using Webdynpro anywhere. We are just calling the webserivce through the Visual Composer iView through the SOAP Message. This is what I coded within the EJB which is exposed as a webservice:

package com.sap.questra.ex;

import java.rmi.RemoteException;

import java.util.Properties;

import javax.ejb.CreateException;

import javax.ejb.SessionBean;

import javax.ejb.SessionContext;

import javax.naming.Context;

import javax.naming.InitialContext;

import javax.naming.NamingException;

import com.sap.mw.jco.JCO;

import com.sap.security.api.IUser;

import com.sap.security.api.IUserFactory;

import com.sap.security.api.UMException;

import com.sap.security.api.UMFactory;

import com.sap.security.api.umap.IUserMapping;

import com.sap.security.api.umap.IUserMappingData;

import com.sap.security.core.server.destinations.api.DestinationException;

import com.sap.security.core.server.destinations.api.DestinationService;

import com.sap.security.core.server.destinations.api.RFCDestination;

/**

  • @ejbHome <{com.sap.questra.ex.ExecuteBAPIHome}>

  • @ejbLocal <{com.sap.questra.ex.ExecuteBAPILocal}>

  • @ejbLocalHome <{com.sap.questra.ex.ExecuteBAPILocalHome}>

  • @ejbRemote <{com.sap.questra.ex.ExecuteBAPI}>

  • @stateless

  • @transactionType Container

*/

public class ExecuteBAPIBean implements SessionBean {

public void ejbRemove() {

}

public void ejbActivate() {

}

public void ejbPassivate() {

}

public void setSessionContext(SessionContext context) {

myContext = context;

}

private SessionContext myContext;

/**

  • Create Method.

*/

public void ejbCreate() throws CreateException {

// TODO : Implement

}

/**

  • Business Method.

*/

public String CreateClient1() {

JCO.Client jcoclient = null;

String S1;

Properties props = new Properties();

try{

String callerPrincipalName = myContext.getCallerPrincipal().getName();

IUserFactory userFactory = UMFactory.getUserFactory();

IUser user = userFactory.getUserByLogonID( callerPrincipalName );

IUserMapping map = UMFactory.getUserMapping();

IUserMappingData mapdata;

mapdata = map.getUserMappingData(null,user);

Context ctx = new InitialContext();

DestinationService dstServ = (DestinationService) ctx.lookup(DestinationService.JNDI_KEY);

if (dstServ == null){

throw new NamingException("Destination Service not available");

}

else{

RFCDestination rfc = (RFCDestination) dstServ.getDestination("RFC","questra.com");

props = rfc.getJCoProperties();

mapdata.enrich(props);

jcoclient = JCO.createClient(props);

S1 = props.getProperty(mapdata.UMAP_JCO_PASSWORD);

}

}

catch(NamingException ex1){

S1 = "Naming Error" + ex1.getMessage();

}

catch(DestinationException ex2){

S1 = "Destination Error" + ex2.getMessage();

}

catch(RemoteException ex3){

S1 = "Remote Error" + ex3.getMessage();

}

catch(UMException ex4){

S1 = "UME Exception" + ex4.getMessage();

}

return S1;

}

}

This EJB just accepts the call and fills the properties with the SSO Information and I am just returning the ticket information through the string. We did a network watch to find the ticket does get created but the exception is still an UME Exception which tells that there is "No Logon Ticket Available"

I hope someone has a workaround to this!

Best regards,

Sudhi

Vlado
Advisor
Advisor
0 Kudos

Hi Sudhi,

Now it's clearer (at least to me) what you are trying to achieve (I got confused by your words "Now I need to get the SAP Logon ticket from the Visual composer application... and pass it on to the EJB") - although I don't see where you do the actual JCo call. Getting the user information from within the EJB looks fine. Guess if you paste the UME Exception details, you could get more help on that here.

Best regards,

Vladimir