Getting the BaseAddress of an HttpClient service from withing a blazor page - web-services

I have a blazor server app that calls an aspx net core web api. In program.cs I setup the application as an HttpClient service and inject it into my web page. In production the entire application (both the service and the blazor app) are delivered on different servers. I need to be able to display the BaseAddress of the web api on a blazor page - the url will be different on different servers of course.
If I inject the service into my blazor page I only get reference to the functions available in the controller, not the properties of the service itself. How can I access the info that was specified in Program.cs for the service?
in Index.razor
`#code {
[Inject]
public MyAspx myservice { get; set; }
protected override async Task OnInitializedAsync()
{
var baseurl = myservice.BaseAddress; // for illustration purposes only this is what i need, not what it will provide
}
}
in Program.cs:
builder.Services.AddHttpClient<IMyAspx, MyAspx>(client =>
{
client.BaseAddress = new Uri("https://localhost:7132/");
client.Timeout = TimeSpan.FromMinutes(1);
});
`

Related

Using soap services(.asmx) with Azure Service fabric

I am migrating my existing services to Azure service fabric. My existing application support the soap service(asmx) for the legacy users. I want to use the same web service as part of my microservice. That web service test.asmx(say) can be called from Rest Apis as well(If soln is there). But I'm not finding any way to use the soap service as part of Azure service fabric microservice approach. Help me out of possible solutions for tackling the web service scenario. Thanks!
I recommend converting your ASMX service into a WCF service with a BasicHttpBinding. You can then host your WCF service inside a stateless SF service, like shown here.
private static ICommunicationListener CreateRestListener(StatelessServiceContext context)
{
string host = context.NodeContext.IPAddressOrFQDN;
var endpointConfig = context.CodePackageActivationContext.GetEndpoint("CalculatorEndpoint");
int port = endpointConfig.Port;
string scheme = endpointConfig.Protocol.ToString();
string uri = string.Format(CultureInfo.InvariantCulture, "{0}://{1}:{2}/", scheme, host, port);
var listener = new WcfCommunicationListener<ICalculatorService>(
serviceContext: context,
wcfServiceObject: new WcfCalculatorService(),
listenerBinding: new BasicHttpBinding(BasicHttpSecurityMode.None),
address: new EndpointAddress(uri)
);
return listener;
}

Automatic NTLM Authentication for WSO2 ESB

I have a WCF Web Service sitting on a client's IIS server secured with NTLM authentication - I have no control over the authentication configuration on that server.
I need to integrate my WSO2 ESB server with this service, but I can't find a way to get the ESB to authenticate automatically. I have successfully pushed requests through the ESB to the service with web applications, but I was prompted to provide my Windows credentials during that process - I would like for this to not happen.
I have attempted to set up an NTLM proxy on my server, but couldn't figure this out either.
Any guidance would be much appreciated.
Strainy
Ok, i found your answer. As you know, WSO2 ESB uses Axis2 for web services. You must add NTLM configuration in Axis2 config file (ESB_HOME/repository/conf/axis2/axis2.xml).
This links, describes the configuration.
http://wso2.com/library/161/
http://axis.apache.org/axis2/java/core/docs/http-transport.html
There were a few components to getting this working correctly. It's hard to find it all written down in one place, so I'll attempt to provide an end-to-end overview here.
I first had to use a class mediator within my WSO2 ESB in-sequence to handle the sending and the NTLM authentication. The class mediator references a custom class which takes the message context from the mediation flow (called the Synapse message context) and extracts the SOAP envelope. I then loaded the Synapse SOAP envelope into an Axis2 message context object. I then used an Axis2 client along with the message context to submit my authenticated request to the server. The authentication for NTLM through Axis2 comes from the JCIFS_NTLMScheme class, which you can reference here.
Note: you'll have to play with the logging configuration in that class to make it work with WSO2. I just removed the " org.sac.crosspather.common.util* " libraries and altered any logging I saw to use the Apache Commons logging capability
Create a Custom Mediator Project in WSO2 Developer Studio
Create a new project in Developer studio. Right click the project node in the project explorer and select "New > Mediator Project".
This will generate a bit of boilerplate code for you - that is, a class which extends AbstractMediator and which implements an "mediate()" method which Synapse will call when it comes to executing the logic defined within your sequence.
public class NTLMAuthorisation extends AbstractMediator {
public boolean mediate(MessageContext context){
//Mediation Logic
return true;
}
}
Expose Some Variables/Properties to the User
The class mediator looks for variables which are publicly accessible and exposes them in the WSO2 configuration. This is helpful before you can create a re-usable mediator which adapts itself to properties or values defined in the WSO2 Carbon Web UI. Here we need to expose seven variables: soapAction, SoapEndpoint, domain, host, port, username, and password. Expose the variables by defining your instance variables, along with their accessors and mutators.
This is all really quite useful for using the WSO2 Secure Vault to store your NTLM password and fetching other configuration from a system registry with properties.
public class NTLMAuthorisation extends AbstractMediator {
private String soapAction;
private String soapEndpoint;
private String domain;
private String host;
private int port;
private String username;
private String password;
public boolean mediate(MessageContext context) {
//Mediation Logic
return true;
}
public void setSoapAction(String _soapAction){
soapAction = _soapAction;
}
public String getSoapAction(){
return soapAction;
}
public void setSoapEndpoint(String _soapEndpoint){
soapEndpoint = _soapEndpoint;
}
public String getSoapEndpoint(){
return soapEndpoint;
}
public void setDomain(String _domain){
domain = _domain;
}
public String getDomain(){
return domain;
}
public void setHost(String _host){
host = _host;
}
public String getHost(){
return host;
}
public void setPort(int _port){
port = _port;
}
public int getPort(){
return port;
}
public void setUsername(String _username){
username = _username;
}
public String getUsername(){
return username;
}
public void setPassword(String _password){
password = _password;
}
public String getPassword(){
return password;
}
}
The Custom Mediation Logic
Make sure you created an JCIFS_NTLMScheme class from here and have added the org.samba.jcifs dependency to your Maven dependencies like so:
<dependency>
<groupId>org.samba.jcifs</groupId>
<artifactId>jcifs</artifactId>
<version>1.3.17</version>
</dependency>
Now you can use the following mediate method in your custom mediator class:
public boolean mediate(MessageContext context) {
//Build NTLM Authentication Scheme
AuthPolicy.registerAuthScheme(AuthPolicy.NTLM, JCIFS_NTLMScheme.class);
HttpTransportProperties.Authenticator auth = new HttpTransportProperties.Authenticator();
auth.setUsername(username);
auth.setPassword(password);
auth.setDomain(domain);
auth.setHost(host);
auth.setPort(port);
ArrayList<String> authPrefs = new ArrayList<String>();
authPrefs.add(AuthPolicy.NTLM);
auth.setAuthSchemes(authPrefs);
//Force Authentication - failures will get caught in the catch block
try {
//Build ServiceClient and set Authorization Options
ServiceClient serviceClient = new ServiceClient();
Options options = new Options();
options.setProperty(org.apache.axis2.transport.http.HTTPConstants.AUTHENTICATE, auth);
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
options.setTo(new EndpointReference(soapEndpoint));
options.setAction(soapAction);
serviceClient.setOptions(options);
//Generate an OperationClient from the ServiceClient to execute the request
OperationClient opClient = serviceClient.createClient(ServiceClient.ANON_OUT_IN_OP);
//Have to translate MsgCtx from Synapse to Axis2
org.apache.axis2.context.MessageContext axisMsgCtx = new org.apache.axis2.context.MessageContext();
axisMsgCtx.setEnvelope(context.getEnvelope());
opClient.addMessageContext(axisMsgCtx);
//Send the request to the server
opClient.execute(true);
//Retrieve Result and replace mediation (synapse) context
SOAPEnvelope result = opClient.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE).getEnvelope();
context.setEnvelope(result);
} catch (AxisFault e) {
context.setProperty("ResponseCode", e.getFaultCodeElement().getText());
return false; //This stops the mediation flow, so I think it executes the fault sequence?
}
return true;
}
Package as an OSGi Bundle and Deploy to the Server
At this stage you should be able to your custom mediator project within the project explorer in WSO2 Developer Studio and from the context menu select Export Project as Deployable Archive. Follow the prompts to save the JAR file somewhere on your system. After generating the JAR file, locate it and transfer it to the [ESB_HOME]/repository/components/dropins directory. You may need to restart the server for it to detect the new external library.
Using the Custom Mediator
In your sequence, you should now be able to add a class mediator and reference your custom class using the package name and class name together, for example: org.strainy.ntlmauthorisation.

Web Service for Gwt Application

What type of web service is supported by gwt application i have tried using Jersey, RESTful, Restlet, but nothing works with GWT. I want to deploy Web-Service on Tomcat and GWT application on app engine.
You can use RPC and RequestBuilder:
https://developers.google.com/web-toolkit/doc/latest/DevGuideServerCommunication
You can also use RESTful services:
How to call RESTFUL services from GWT?
Thanx all for your suport . . i have got the answer for my question.
i created a restfull web service using Jersey and called it using the following code in my gwt app engine application:
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource service = client.resource(UriBuilder.fromUri("http://localhost:8080/de.vogella.jersey.first").build());
String obj=service.path("rest").path("bye").accept(MediaType.TEXT_PLAIN).get(String.class);
and the web application code is :
package de.vogella.jersey.first;
import javax.ws.rs.*;
#Path("/bye")
public class Hello {
// This method is called if TEXT_PLAIN is request
#GET
#Produces(MediaType.TEXT_PLAIN)
public String sayPlainTextHello() {
return "Hello it worked";
}
For Web Application Code refer to this link:
http://www.vogella.com/articles/REST/article.html

Cannot deploy web service in GlassFish using together #WebserviceProvider and #Stateless

I tried to deploy in GlassFish JAX-WS web service,
Here is a snippet of class were the web service is defined. Pay attention that I implemented Provider interface on EJB endpoint.
#Stateless(name = "HelloWorldEJBWS")
#WebServiceProvider(
portName = "HelloWorldWSPort",
serviceName = "HelloWorldWSService",
targetNamespace = "http://ivan.com/",
wsdlLocation ="HelloWorldEJBProvider.wsdl")
#ServiceMode(value = Service.Mode.PAYLOAD)
public class HelloWorldEJBWS implements Provider<Source> {
public Source invoke(final Source inRequestMessage) {
...
}
}
The problem is about the deploying the service in GlassFish (3.1.2.2) . F.
[#|2012-09-08T16:39:15.682-0400|INFO|glassfish3.1.2|javax.enterprise.system.container.ejb.com.sun.ejb.containers|_ThreadID=20;_ThreadName=Thread-2;|EJB5181:Portable JNDI names for EJB HelloWorldEJBWS: [java:global/JAX-WS_GreetingEJBMutualAuthProvider/HelloWorldEJBWS, java:global/JAX-WS_GreetingEJBMutualAuthProvider/HelloWorldEJBWS!javax.xml.ws.Provider]|#]
[#|2012-09-08T16:39:15.792-0400|INFO|glassfish3.1.2|javax.enterprise.webservices.org.glassfish.webservices|_ThreadID=20;_ThreadName=Thread-2;|WS00019: EJB Endpoint deployed
JAX-WS_GreetingEJBMutualAuthProvider listening at address at http://ABRAMOV1:8088/HelloWorldWSService/com.ivan.wsejb.provider.HelloWorldEJBWS|#]
Even it shows the endpoint is deployed - is not . I can't reach this endpoint and it is not shown in GlassFish console.
For comparison I provide the log when I deployed the service using #WebService but not #WebServiceProvider
[#|2012-09-08T16:41:50.514-0400|INFO|glassfish3.1.2|javax.enterprise.webservices.org.glassfish.webservices|_ThreadID=22;_ThreadName=Thread-2;|WS00019: EJB Endpoint deployed
JAX-WS_GreetingEJBMutualAuth listening at address at http://ABRAMOV1:8088/HelloWorldEJBWSService/HelloWorldEJBWS|#]
In this case endpoint deployed correctly and everything is working fine.
Here is snipped of the code when I apply #WebService
#Stateless(name = "HelloWorldEJBWS")
#WebService()
public class HelloWorldEJBWS {
public String hello(final String inMessage) {
...
}
}
Did I do something wrong ?
I did everything right but was mislead by GlassFish. It could be a a bug...
When I deploy web service with endpoint implemented as servlet (second case) in the console I can see endpoint, but in case with endpoint implemented as EJB the endpoint did not appear in the console. But I could access the WSDL with a link http://localhost:8088/HelloWorldWSService/com.ivan.wsejb.provider.HelloWorldEJBWS?wsdl and ultimately tested web service with the client

Rich client (swing) application which connects to Remote database over http

i have a local client j2se application and backend is derby(javadb) database and dao is jpa eclipselink .
how do i send these database pojo to a remote database which linked with spring ( jsp) application on tomcat server
simply this is a rich client with swing which connects to tomcat deployed web application. The client should receive data and send data through HTTP requests to the server-side of the service,
what would be the best solution ??
01) direct database connection/transaction through socket using Eclipselink
02) web service ??
03) just send post request to spring web application and convert it to POJO and persist to database
how do i achieve this??
DISCLAIMER I am not suggesting you port your app from Spring to EJB. Despite how people like to compare them as exclusively one or the other, you can use them both. Its your app, you can be as pragmatic as you want to be :)
You don't necessarily have to use Web Services if you wanted. You could drop the OpenEJB war file into Tomcat as well and create an Remote EJB to send data back and forth.
Once you drop in OpenEJB you can put a remote #Stateless bean in your app like so:
#Stateless
#Remote
public class MyBean implements MyBeanRemote {
//...
}
public interface MyBeanRemote {
// any methods you want remotely invoked
}
Then look it up and execute it over HTTP from your Swing app like so:
Properties p = new Properties();
p.put("java.naming.factory.initial", "org.apache.openejb.client.RemoteInitialContextFactory");
p.put("java.naming.provider.url", "http://tomcatserver:8080/openejb/ejb");
// user and pass optional
p.put("java.naming.security.principal", "myuser");
p.put("java.naming.security.credentials", "mypass");
InitialContext ctx = new InitialContext(p);
MyBean myBean = (MyBean) ctx.lookup("MyBeanRemote");
Client-side all you need are the openejb-client.jar and javaee-api.jar from the OpenEJB war file and your own classes.
Since it's already a Spring app don't bother trying to use #PersistenceContext to get a reference to the EntityManager so the EJB can use it. Just figure out how to expose the EntityManagerFactory that Spring creates (or you create) to the EJB via any means possible. The direct and ugly, but effective, approach would be a static on the MyBean class and a bit of startup logic that sets it. You'd just be using the EJB for remoting so no need for fancier integration.
If you did really need web services for non-java communication or something, you can add #WebService to the top of your bean and then it will have WSDL and all that generated for it:
#Stateless
#Remote
#WebService(portName = "MyBeanPort",
serviceName = "MyBeanService",
targetNamespace = "http://superbiz.org/wsdl"
endpointInterface = "org.superbiz.MyBeanRemote")
public class MyBean implements MyBeanRemote {
//...
}
public interface MyBeanRemote {
// any methods you want remotely invoked
}
Then you can also use the same bean as a web service like:
Service service = Service.create(
new URL("http://tomcatserver:8080/MyBeanImpl?wsdl"),
new QName("http://superbiz.org/wsdl", "MyBeanService"));
assertNotNull(service);
MyBeanRemote myBean = service.getPort(MyBeanRemote.class);
Both approaches are over http, but the web service approach will be a bit slower as it isn't a binary protocol.