Insert TYPE_NUTRITION in Google Fit - google-fit

I get user input (calorie) and want to insert it in Google Fit but the insertion does not work.
private DataSet insertNutritionData(){
Calendar cal = Calendar.getInstance();
Date now = new Date();
cal.setTime(now);
long endTime = cal.getTimeInMillis();
DataSource nutritionSource = new DataSource.Builder()
.setAppPackageName(getApplicationContext().getPackageName())
.setDataType(DataType.TYPE_NUTRITION)
.setType(DataSource.TYPE_RAW)
.build();
DataSet dataSet = DataSet.create(nutritionSource);
DataPoint dataPoint = DataPoint.create(nutritionSource);
dataPoint.setTimestamp(endTime, TimeUnit.MILLISECONDS);
dataPoint.getValue(Field.FIELD_NUTRIENTS).setKeyValue(Field.NUTRIENT_CALORIES,calorie);
dataSet.add(dataPoint);
return dataSet;
}
The insertion is done in AsyncTask :
private class InsertAndVerifyNutritionTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
DataSet dataSet = insertNutritionData();
Log.i(TAG, "Inserting the dataset in the History API");
com.google.android.gms.common.api.Status insertStatus =
Fitness.HistoryApi.insertData(mClient, dataSet)
.await(1, TimeUnit.MINUTES);
if (!insertStatus.isSuccess()) {
Log.i(TAG, "There was a problem inserting the dataset.");
return null;
}
Log.i(TAG, "Data insert was successful!");
return null;
}
}
Unfortunately, the insertion is not done and I don't know why. There is no sample to explain how can we use TYPE_NUTRIENTS...
Thanks a lot !
[UPDATE]
I found this error :
Couldn't connect to Google API client: ConnectionResult{statusCode=API_UNAVAILABLE, resolution=null}
However, I build my client like this :
mClient = new GoogleApiClient.Builder(this)
.addApi(Fitness.RECORDING_API)
.addApi(Fitness.SENSORS_API)
.addApi(Fitness.HISTORY_API)
.addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE))
.addScope(new Scope(Scopes.FITNESS_NUTRITION_READ_WRITE))
.addConnectionCallbacks(
new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Google Fit connected.");
mTryingToConnect = false;
Log.d(TAG, "Notifying the UI that we're connected.");
notifyUiFitConnected();
}
#Override
public void onConnectionSuspended(int i) {
// If your connection to the sensor gets lost at some point,
// you'll be able to determine the reason and react to it here.
mTryingToConnect = false;
if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST) {
Log.i(TAG, "Connection lost. Cause: Network Lost.");
} else if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
Log.i(TAG, "Connection lost. Reason: Service Disconnected");
}
}
}
)
.addOnConnectionFailedListener(
new GoogleApiClient.OnConnectionFailedListener() {
// Called whenever the API client fails to connect.
#Override
public void onConnectionFailed(ConnectionResult result) {
//Toast.makeText(getActivity(),"connection failed 1",Toast.LENGTH_SHORT).show();
mTryingToConnect = false;
notifyUiFailedConnection(result);
}
}
)
.build();
}
Moreover, I don't understand why I cannot connect to fit whereas it worked perfectly...
Updated with the manifest :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.webear.mysilhouette">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:allowBackup="true"
android:label="mySilhouette"
android:icon="#drawable/ic_launcher"
>
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<service
android:enabled="true"
android:name="com.example.webear.mysilhouette.GoogleApiIntentService"/>
(...)
</application>
</manifest>
Kamel

The statusCode says API_UNAVAILABLE. It means:
One of the API components you attempted to connect to is not
available. The API will not work on this device, and updating Google
Play services will not likely solve the problem. Using the API on the
device should be avoided.
Maybe try another device? Or Play Services are misconfigured.

Related

Android: Saved video file cant be played

I have developed an app that can play videos from gallery and then save the played video back into a folder in gallery. The app is working fine as I can select and play videos from gallery and then save it. When the "Save Video' button is clicked, 'Video saved!' message pops and the saved video are found in gallery. The issue now is I cant play the video, it says 'Sorry, this video cannot be played'. Im unable to identify where it went wrong. My codings are as follow:
AndroidVideoPlayer.java:
public class AndroidVideoPlayer extends Activity {
/**
* Called when the activity is first created.
*/
Button button, button2;
VideoView videoView;
private static final int PICK_FROM_GALLERY = 1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_android_video_player);
button = (Button) findViewById(R.id.button);
button2 = (Button) findViewById(R.id.savevideo);
videoView = (VideoView) findViewById(R.id.videoview);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setType("video/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Complete action using"), PICK_FROM_GALLERY);
}
});
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
savequesimage();
// Toast.makeText(getActivity(), "Sample Answer Saved", Toast.LENGTH_LONG).show();
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK) return;
if (requestCode == PICK_FROM_GALLERY) {
Uri mVideoURI = data.getData();
videoView.setVideoURI(mVideoURI);
videoView.start();
}
}
protected boolean savequesimage() {
boolean success = false;
View content = videoView;
content.invalidate();
// make the directory
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/SavedVideo/";
File dir = new File(path);
if(!dir.exists())
dir.mkdirs();;
// create unique identifier
Random generator = new Random();
int n = 100;
n = generator.nextInt(n);
// create file name
String videoName = "Video_" + n + ".mp4";
File fileVideo = new File(dir.getAbsolutePath(), videoName);
try {
fileVideo.createNewFile();
success = true;
} catch (IOException e) {
e.printStackTrace();
}
if (success) {
Toast.makeText(getApplicationContext(), "Video saved!",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),
"Error during video saving", Toast.LENGTH_LONG).show();
}
return true;
}
}
activity_android_video_player.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:id="#+id/button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="- PLAY Video -"
/>
<Button
android:id="#+id/savevideo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="- Save Video -"
/>
<VideoView
android:id="#+id/videoview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mainapp.videoview" >
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".AndroidVideoPlayer"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Can anyone help me to resolve this issue? Any help/suggestion would be really helpful. Thank you.
Firstly, add permission READ_EXTERNAL_STORAGE & WRITE_EXTERNAL_STORAGE to AndroidManifest.xml like this:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
With Android Level >=23 you need ask permission in code:
// With Android Level >= 23 you need ask permission.
if (android.os.Build.VERSION.SDK_INT >= 23) {
// Check if we have write & read permission
int writePermission = this.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
int readPermission = this.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE);
if (writePermission != PackageManager.PERMISSION_GRANTED ||
readPermission != PackageManager.PERMISSION_GRANTED) {
// If don't have permission so prompt the user.
this.requestPermissions(
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_PERMISSION
);
}
}
See more here.

Setting up WNS service for windows phone 8 get error after add <Identity> tag

I am setting up windows phone 8.1 push notification with urbanairship. I have SID and Secret key for my app. But when i do following step mentioned in dev.windows WNS-->Live Service site:
To set your application's identity values manually, open the
AppManifest.xml file in a text editor and set these attributes of the
element using the values shown here.
my application is stop working. is any one provide me steps for set up WNS in windows phone 8.1 then it helps me a lot, I spend over the week on this and now really frustrating.
I got success with Push Notification in Windows Phone 8.1/ Windows Apps (Universal Apps). I have implemented sending Push Notification to devices from our own Web Service.
Step 1: Get the Client Secret and Package SID from the dev.windows.com >> Services >> Live Services. You'll need these later in Web Service.
Step 2: In your Windows App, you have to associate your app with the Store. For that, Right click on project >> Store >> Associate App with the Store. Log in with your Dev account and associate your app.
Step 3
You'll need a Channel Uri.
In the MainPage.xaml, add a Button and a Textblock to get your Channel Uri.
XAML Code looks like this:
<Page
x:Class="FinalPushNotificationTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:FinalPushNotificationTest"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="Push Notification" Margin="20,48,10,0" Style="{StaticResource HeaderTextBlockStyle}" TextWrapping="Wrap" />
<ScrollViewer Grid.Row="1" Margin="20,10,10,0">
<StackPanel x:Name="resultsPanel">
<Button x:Name="PushChannelBtn" Content="Get Channel Uri" Click="PushChannelBtn_Click" />
<ProgressBar x:Name="ChannelProgress" IsIndeterminate="False" Visibility="Collapsed" />
<TextBlock x:Name="ChannelText" FontSize="22" />
</StackPanel>
</ScrollViewer>
</Grid>
Step 4:
In the MainPage.xaml.cs page, Add the following code snippet i.e. for the Button Click Event. When you run your app, you'll get the Channel Uri in the Console Window. Note down this Channel Uri, you'll need that in Web Service.
private async void PushChannelBtn_Click(object sender, RoutedEventArgs e)
{
var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
ChannelText.Text = channel.Uri.ToString();
Debug.WriteLine(channel.Uri);
}
Step 5:
Now You need a Web Service to send push notification to your device. For that Right Click on your project in Solution Explorer. Add >> New Project >> Visual C# >> Web >> ASP.NET Web Application. Click OK, On Template select Empty. After that Add a new Web Form in your Web Application. Name it SendToast.
Step 6:
Now In the SendToast.aspx.cs, you need to implement methods and functions to get the Access Token using Package SID, Client Secret and Channel Uri. Add your Package SID, Cleint Secret, and Channel Uriin respective places.
The complete code looks like the following code snippet:
using Microsoft.ServiceBus.Notifications;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace SendToast
{
public partial class SendToast : System.Web.UI.Page
{
private string sid = "Your Package SID";
private string secret = "Your Client Secret";
private string accessToken = "";
[DataContract]
public class OAuthToken
{
[DataMember(Name = "access_token")]
public string AccessToken { get; set; }
[DataMember(Name = "token_type")]
public string TokenType { get; set; }
}
OAuthToken GetOAuthTokenFromJson(string jsonString)
{
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
{
var ser = new DataContractJsonSerializer(typeof(OAuthToken));
var oAuthToken = (OAuthToken)ser.ReadObject(ms);
return oAuthToken;
}
}
public void getAccessToken()
{
var urlEncodedSid = HttpUtility.UrlEncode(String.Format("{0}", this.sid));
var urlEncodedSecret = HttpUtility.UrlEncode(this.secret);
var body =
String.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=notify.windows.com", urlEncodedSid, urlEncodedSecret);
var client = new WebClient();
client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
string response = client.UploadString("https://login.live.com/accesstoken.srf", body);
var oAuthToken = GetOAuthTokenFromJson(response);
this.accessToken = oAuthToken.AccessToken;
}
protected string PostToCloud(string uri, string xml, string type = "wns/toast")
{
try
{
if (accessToken == "")
{
getAccessToken();
}
byte[] contentInBytes = Encoding.UTF8.GetBytes(xml);
WebRequest webRequest = HttpWebRequest.Create(uri);
HttpWebRequest request = webRequest as HttpWebRequest;
webRequest.Method = "POST";
webRequest.Headers.Add("X-WNS-Type", type);
webRequest.Headers.Add("Authorization", String.Format("Bearer {0}", accessToken));
Stream requestStream = webRequest.GetRequestStream();
requestStream.Write(contentInBytes, 0, contentInBytes.Length);
requestStream.Close();
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
return webResponse.StatusCode.ToString();
}
catch (WebException webException)
{
string exceptionDetails = webException.Response.Headers["WWW-Authenticate"];
if ((exceptionDetails != null) && exceptionDetails.Contains("Token expired"))
{
getAccessToken();
return PostToCloud(uri, xml, type);
}
else
{
return "EXCEPTION: " + webException.Message;
}
}
catch (Exception ex)
{
return "EXCEPTION: " + ex.Message;
}
}
protected void Page_Load(object sender, EventArgs e)
{
string channelUri = "Your Channel Uri";
if (Application["channelUri"] != null)
{
Application["channelUri"] = channelUri;
}
else
{
Application.Add("channelUri", channelUri);
}
if (Application["channelUri"] != null)
{
string aStrReq = Application["channelUri"] as string;
string toast1 = "<?xml version=\"1.0\" encoding=\"utf-8\"?> ";
string toast2 = #"<toast>
<visual>
<binding template=""ToastText01"">
<text id=""1"">Hello Push Notification!!</text>
</binding>
</visual>
</toast>";
string xml = toast1 + toast2;
Response.Write("Result: " + PostToCloud(aStrReq, xml));
}
else
{
Response.Write("Application 'channelUri=' has not been set yet");
}
Response.End();
}
}
}
Run your web application, you'll get the Result OK response if it successfully sends push notification.
Let me know if you need working sample project.
Hope this helps.
Thanks!

How to display retrieved image from mysql in jsp. I am using struts2 and tiles

I am using strust2 and tiles for my project. Here is the code (jsp) for entering an ID.
<s:textfield name="uniqueID" label="Enter Unique ID" required="required"/>
Here is the action file.
public String execute() throws Exception{
SearchDao.search(selectedID,uniqueID);
return SUCCESS;
}
The dao will retrieve image.
try{
.
.
.
rs = ps.executeQuery();
if(rs.next()){
InputStream originalImageStream = rs.getBinaryStream(1);
File file = new File("Retina"+".jpg");
FileOutputStream fileOutputStream = new FileOutputStream(file);
while ((length = originalImageStream.read()) != -1) {
fileOutputStream.write(length);
}
fileOutputStream.close();
}
else{
return null;
}
}
catch(Exception ex){
ex.printStackTrace();
}
return "found";
Once the image is found this will return found and so action file will return success. Code in struts.xml is
<action name="search" class="com.ActionClasses.SearchAction">
<result name="success" type="tiles"> found </result>
<result name="input" type="tiles"> search </result>
<result name="error" type="tiles"> notFound </result>
</action>
here is the tiles.xml file.
<definition name="found" extends="home">
<put-attribute name="myTitle" value="searchSuccess"/>
<put-attribute name="myBody" value="/found.jsp"/>
</definition>
Now how can I display the retrieved image in found.jsp. I found some solutions in Internet but only for projects that uses struts2 or struts2 along with hibernate. I didn't find any solution for projects that use both strus2 and tiles. Can anyone help me. Thank you.
Try this out ... I have implemented the similar scenario in one of my projects but in spring, I guess it should work for you with little changes
This is what I had implemented. I created a controller (aka action in struts) like below
#RequestMapping(value = "view", method = RequestMethod.GET)
public void getImage(#RequestParam(value = "location") String location, HttpServletResponse response) {
String ext = FilenameUtils.getExtension(location);
response.setContentType("image/"+ext);
try {
File file = new File(location);
BufferedImage image = ImageIO.read(file);
OutputStream baos = response.getOutputStream();
ImageIO.write(image, ext, baos);
baos.flush();
baos.close();
} catch (FileNotFoundException e) {
logger.error("File Not Found: " + location, e);
} catch (IOException e) {
logger.error("Can't read the File: " + location, e);
} catch(Exception e) {
logger.error("Can't read input file: " + location, e);
}
return;
}
And then in the controller/action that server the actual view I did something like this
final String IMAGE_RESOLVER = "../../image/view?location=";
Game game = gameService.populateGame(gameId);
if(game.getThumbnailPath() != null) {
game.setThumbnailPath(IMAGE_RESOLVER.concat(game.getThumbnailPath()));
}
mv.addObject("game", game); // set object to return to view
When the DOM object with name "thumbnail" receives this string it calls the action mentioned above which returns it an image
Hope this works for you

Embedded Google Map can't get current location in WebView

I followed this tutorial: http://android-er.blogspot.com/2013/03/embed-google-map-in-webview.html
I'm trying to just use the Google Map in the WebView, but it can't get my current location. I've enabled JavaScript on the WebView. What else do I have to enable?
Does anyone know why that might be? Shouldn't it prompt me to use my current location?
Note that I am not interested in using a MapView as an alternative whatsoever. I'm trying to find out what I need to set on the WebView or maybe on the device's location services?
You should permit the web view to access your location by overriding the method onGeolocationPermissionsShowPrompt like this:
webView.setWebChromeClient(new WebChromeClient(){
#Override
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
callback.invoke(origin, true, false);
}
});
On API 5.x and below, you will need
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
in your AndroidManifest.xml.
But to allow permissions for geolocation on API 6.0+, you have to request the permission at runtime.
To do this, use
private String mGeolocationOrigin;
private GeolocationPermissions.Callback mGeolocationCallback;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// other setup
myWebView.setWebChromeClient(new MyWebChromeClient());
}
private WebChromeClient mWebChromeClient = new WebChromeClient() {
#Override
public void onGeolocationPermissionsShowPrompt(String origin,
GeolocationPermissions.Callback callback) {
// Geolocation permissions coming from this app's Manifest will only be valid for devices with API_VERSION < 23.
// On API 23 and above, we must check for permission, and possibly ask for it.
final String permission = Manifest.permission.ACCESS_FINE_LOCATION;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M ||
ContextCompat.checkSelfPermission(MainActivity.this, permission) == PackageManager.PERMISSION_GRANTED) {
// we're on SDK < 23 OR user has already granted permission
callback.invoke(origin, true, false);
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, permission)) {
// user has denied this permission before and selected [/] DON'T ASK ME AGAIN
// TODO Best Practice: show an AlertDialog explaining why the user could allow this permission, then ask again
} else {
// ask the user for permissions
ActivityCompat.requestPermissions(MainActivity.this, new String[] {permission}, RP_ACCESS_LOCATION);
mGeolocationOrigin = origin;
mGeolocationCallback = callback;
}
}
}
}
and receive the result:
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case RP_ACCESS_LOCATION:
boolean allow = false;
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// user has allowed these permissions
allow = true;
}
if (mGeolocationCallback != null) {
mGeolocationCallback.invoke(mGeolocationOrigin, allow, false);
}
break;
}
}
in your activity.
You can try GreenDroid with Google Maps.
Checkt it out: https://github.com/cyrilmottier/GreenDroid
You'd have to enable android.permission.ACCESS_FINE_LOCATION and android.permission.INTERNET,
Create a LocationManager instance and LocationListener instance
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
LocationListener locationListener = new MyLocationListener();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 10, locationListener);
and add onLocationChanged(Location loc) method that inside of it have your loc generate the longitude and latitude (String long = loc.getLongitude(); String lat = loc.getLatitude();)
and now use long, lat to generate your mapPath string and continue to generate the WebView
You can use this for ref: http://www.rdcworld-android.blogspot.in/2012/01/get-current-location-coordinates-city.html

How to keep inbound host with custom Mule ESB router

I created a custom router with one endpoint. The custom router looks up the destination of the endpoint based on the URL parameters of the inbound URL. I have an example of this up and running, and I am testing it out in a browser. I am trying to solve one last thing with this. When I make the call in the browser using http://localhost:8787/my-site, the call makes a redirect and the URL in the browser changes to http://server2.xyz.com:8080/my-site. I don't want the user to ever see http://server2.xyz.com:8080/my-site. I want the user to always see http://localhost:8787/my-site. How can I achieve this? I am using Mule 2.2.1 community edition with Java 1.6.
Here is my Mule configuration file:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesource.org/schema/mule/core/2.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:http="http://www.mulesource.org/schema/mule/http/2.2"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.mulesource.org/schema/mule/core/2.2 http://www.mulesource.org/schema/mule/core/2.2/mule.xsd
http://www.mulesource.org/schema/mule/http/2.2 http://www.mulesource.org/schema/mule/http/2.2/mule-http.xsd">
<model name="ProxyService">
<service name="HttpProxyService">
<inbound>
<http:inbound-endpoint address="http://localhost:8787" synchronous="true"/>
</inbound>
<outbound>
<custom-outbound-router class="com.abc.xyz.routing.LookupOutboundRouter">
<outbound-endpoint name="custom" address="http://nonexistant.server.com:8080" synchronous="true"/>
</custom-outbound-router>
</outbound>
</service>
</model>
</mule>
Here is my custom router:
public class LookupOutboundRouter extends AbstractOutboundRouter {
Logger logger = Logger.getLogger(LookupOutboundRouter.class);
#Override
public boolean isMatch(MuleMessage message) throws MessagingException {
return true;
}
#Override
public MuleMessage route(MuleMessage message, MuleSession session) throws MessagingException {
String[] urlValues = StringUtils.split(message.getProperty("http.request").toString(), "/");
String newUri = lookupServiceUri(urlValues[0]) + urlValues[1];
logger.info("newUri=" + newUri);
DynamicURIOutboundEndpoint ep;
try {
ep = new DynamicURIOutboundEndpoint((OutboundEndpoint) getEndpoints().get(0), new MuleEndpointURI(newUri));
MuleMessage message2 = send(session, message, ep);
return message2;
} catch (EndpointException e1) {
e1.printStackTrace();
} catch (MuleException e) {
e.printStackTrace();
}
return null;
}
/**
* This will call the service registry.
* #param id
* #return
*/
private String lookupServiceUri(String id) {
if(id.equalsIgnoreCase("12345")) {
return "http://server.xyz.com:8080/";
} else {
return "http://server2.xyz.com:8080/";
}
}
}
I was able to achieve this in the browser by setting followRedirects to true on the HTTP connector. The only issue with this now is that it does not work for POST redirects. I'm making a SOAP call from SoapUI now instead of using the browser.
Entity enclosing requests cannot be redirected without user intervention
Message : Failed to route event via endpoint: org.mule.endpoint.DynamicURIOutboundEndpoint#fd285ee0. Message payload is of type: PostMethod
Type : org.mule.api.transport.DispatchException
Code : MULE_ERROR-42999
Payload : org.apache.commons.httpclient.methods.PostMethod#9fa8f
JavaDoc : http://www.mulesource.org/docs/site/current2/apidocs/org/mule/api/transport/DispatchException.html