Cross origin request (COR) with embedded jetty - jetty

I have a KML Server that outputs KML data and that I can configure as network place in Google Earth. The KML Server uses embedded Jetty.
I would like to also run the KML Server under Cecium, but then I need to configure Jetty to allow COR. Cesium runs from a webbowser.
There are many example w.r.t. Jettty/COR, but many of them do not run, are outdated, and are just unclear.
The KML Server main program is:
/*
** Create HHTP server
*/
final Server server = new Server(config.getKmlPortNumber());
// Set a handler for each context
ContextHandlerCollection contexts = new ContextHandlerCollection();
Handler[] contextHandler = new Handler[ForceIdentifier.TOTAL_IDENTIFIERS + 1];
final ContextHandler context = new ContextHandler("/");
context.setContextPath("/");
context.setHandler(new DefaultHandler(env));
contextHandler[0] = context;
// Set a handler for each Force Identifier.
for (byte i = 0; i < ForceIdentifier.TOTAL_IDENTIFIERS; i++) {
ContextHandler contexti = new ContextHandler("/" + i);
contexti.setHandler(new DefaultHandler(env, new ForceIdentifier(i)));
contextHandler[i + 1] = contexti;
}
contexts.setHandlers(contextHandler);
server.setHandler(contexts);
// Start the server and set some options
server.start();
//server.dumpStdErr();
server.setStopTimeout(1000);
server.setStopAtShutdown(true);
/*
** Start the federate
*/
try {
federate.start();
} catch (RTIexception ex) {
Main.logger.log(Level.SEVERE, null, ex);
}
/*
** Stop the federate
*/
federate.stop();
The KML Server uses serveral context handlers.
What needs to be done to enable COR here?
(Jetty version is: jetty-all-9.2.10.v20150310)

org.eclipse.jetty.servlets.CrossOriginFilter the technique that Jetty has for enabling COR related features, is only available under a ServletContext, meaning your example code, which doesn't use Servlets, or a ServletContext cannot utilize this filter.
You can, however, make your own Handler to do the COR related work for your servlet-free environment. (Consider looking at the cougar project, and its CrossOriginHandler implementation for inspiration)
Or you can switch to using a ServletContextHandler instead of a ContextHandler and then gain the benefit of using Jetty CrossOriginFilter in your project.

Related

is there any replacement class of WebSocketServerFactory in jetty 10?

Jetty 9 has WebSocketServerFactory class but in jetty 10 there is no such class present.
What is the alternative way without using WebSocketServerFactory?
Below factory class created in jetty 9. Now I want to upgrade to jetty 10 but facing difficulties. any suggestions please!!
public class UpgradeSocketServerFactory extends WebSocketServerFactory
{
private static final Executor executor = CustomExecutors.newFabricCachedThreadPool(10, "jetty-threads");
private static final ByteBufferPool bufferPool = new ArrayByteBufferPool(0, 0, 64*1024);
public UpgradeSocketServerFactory(WebSocketPolicy policy)
{
super(policy, executor, bufferPool);
}
#Override
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
{
return new sendCustomObject();
}
}
Note: UpgradeSocketServerFactory Contractor calling from other class.
Since your question was unclear about the struggles you are having, I'll just assume it's the createWebSocket() method. If this is not the case, use the Question section at the official issue tracker to have a conversation about your struggles (stackoverflow is for narrow focused and specific development questions)
https://github.com/eclipse/jetty.project/issues/new/choose
The WebSocketCreator is still there, that's how you should be using the WebSocketServletFactory and/or WebSocketServerFactory.
Steps to take:
change your Jetty 9 code to NOT extend from WebSocketServerFactory
use WebSocketCreator instead to create a custom websocket instance of your endpoint
register your WebSocketCreator by mapping it to a URL pathSpec.
Use the NativeWebSocketServerContainerInitializer.configure() in your embedded code to do that.
See: https://github.com/jetty-project/embedded-jetty-websocket-examples/blob/9.4.x/native-jetty-websocket-example/src/main/java/org/eclipse/jetty/demo/EventServer.java
Jetty 9 technique
// Setup the basic application "context" for this application at "/"
// This is also known as the handler tree (in jetty speak)
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);
// Configure specific websocket behavior
NativeWebSocketServletContainerInitializer.configure(context,
(servletContext, nativeWebSocketConfiguration) ->
{
// Configure default max size
nativeWebSocketConfiguration.getPolicy().setMaxTextMessageBufferSize(65535);
// Add websockets
nativeWebSocketConfiguration.addMapping("/events/*", new EventEndpointCreator());
});
// Add generic filter that will accept WebSocket upgrade.
WebSocketUpgradeFilter.configure(context);
Now, time to upgrade to Jetty 10/11.
Change name of WebSocketCreator to JettyWebSocketCreator
You'll use JettyWebSocketServletContainerInitializer.configure() instead.
See: https://github.com/jetty-project/embedded-jetty-websocket-examples/blob/11.0.x/native-jetty-websocket-example/src/main/java/org/eclipse/jetty/demo/EventServer.java
Jetty 11 technique
// Setup the basic application "context" for this application at "/"
// This is also known as the handler tree (in jetty speak)
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);
// Configure specific websocket behavior
JettyWebSocketServletContainerInitializer.configure(context, (servletContext, wsContainer) ->
{
// Configure default max size
wsContainer.setMaxTextMessageSize(65535);
// Add websockets
wsContainer.addMapping("/events/*", new EventEndpointCreator());
});

Apply HTTP basic authentication to jax ws (HttpSpiContextHandler) in embedded Jetty

There are some similar questions for earlier versions of Jetty (pre 9) but none that address this specific problem :
Server server = new Server();
System.setProperty("com.sun.net.httpserver.HttpServerProvider",
JettyHttpServerProvider.class.getName());
JettyHttpServer jettyServer = new JettyHttpServer(server, true);
Endpoint endpoint = Endpoint.create(new SOAPService()); // this class to handle all ws requests
endpoint.publish(jettyServer.createContext("/service")); // access by path
server.start()
Simplified code example above to show the only way that I have found to bridge between Jetty and incoming soap requests to my jax-ws service. All settings are in code with no web.xml, this is part of a larger solution that has multiple contexts and connections for different purposes (servlets etc..)
I have tried to add a handler class to the jettyServer.createContext("/service",new handler()) to see if I can perform a header extraction to simulate basic auth but it never gets executed.
My problem is that i cannot find a way to specify, by code against the Jetty server, to use basic authentication. Using the setSecurityHandler method of a ServletContextHandler is easy and works great for other contexts, i just can't figure out how to use this concept for the jax-ws service.
Any help would be much appreciated.
p.s. SSL is already implemented, I just need to add http basic auth.
For anyone else that may of come across the same problem here is the answer that i stumbled on eventually.
final HttpContext httpContext = jettyServer.createContext("/service");
com.sun.net.httpserver.BasicAuthenticator a = new com.sun.net.httpserver.BasicAuthenticator("") {
public boolean checkCredentials (String username, String pw)
{
return username.equals("username") && pw.equals("password");
}
};
httpContext.setAuthenticator(a);
endpoint.publish(httpContext);//access by path
You can expand the checkCredentials for something a bit more sophisticated of course, but this shows the basic working method.

ApplyChangeFailed does not fired on conflict

I'm trying to sync two SQL Server DBs by following Microsoft example from here Synchronizing SQL Server and SQL Express and the basic sync is working for me.
Now, I tried to create a conflict by changing the same row on both DB to different values but when I run my sync process the ApplyChangeFailed is not fired.
I read this question Microsoft Sync Framework Conflict Event does not fire but I don't understand why when I sync client<->server configuration the framework ignore conflicts.
Here is my code, just for reference, I have a remote SQL 2008 R2 Server as the server and a local SQL 2012 Express as the client:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using Microsoft.Synchronization;
using Microsoft.Synchronization.Data;
using Microsoft.Synchronization.Data.SqlServer;
using Microsoft.Synchronization.Data.SqlServerCe;
namespace ExecuteExpressSync
{
class Program
{
static void Main(string[] args)
{
SqlConnection clientConn = new SqlConnection(#"Data Source=.\SQLEXPRESS; Initial Catalog=SyncExpressDB; Trusted_Connection=Yes");
SqlConnection serverConn = new SqlConnection("Data Source=X.Y.Z.W; Initial Catalog=SyncDB; uid=sa;password=******;Integrated Security=False");
// create the sync orhcestrator
SyncOrchestrator syncOrchestrator = new SyncOrchestrator();
// set local provider of orchestrator to a sync provider associated with the
// ProductsScope in the SyncExpressDB express client database
syncOrchestrator.LocalProvider = new SqlSyncProvider("ProductsScope", clientConn);
// set the remote provider of orchestrator to a server sync provider associated with
// the ProductsScope in the SyncDB server database
syncOrchestrator.RemoteProvider = new SqlSyncProvider("ProductsScope", serverConn);
// set the direction of sync session to Upload and Download
syncOrchestrator.Direction = SyncDirectionOrder.UploadAndDownload;
// subscribe for errors that occur when applying changes to the client
((SqlSyncProvider)syncOrchestrator.LocalProvider).ApplyChangeFailed += new EventHandler<DbApplyChangeFailedEventArgs>(Program_ApplyChangeFailed);
// execute the synchronization process
SyncOperationStatistics syncStats = syncOrchestrator.Synchronize();
// print statistics
Console.WriteLine("Start Time: " + syncStats.SyncStartTime);
Console.WriteLine("Total Changes Uploaded: " + syncStats.UploadChangesTotal);
Console.WriteLine("Total Changes Downloaded: " + syncStats.DownloadChangesTotal);
Console.WriteLine("Complete Time: " + syncStats.SyncEndTime);
Console.WriteLine(String.Empty);
}
static void Program_ApplyChangeFailed(object sender, DbApplyChangeFailedEventArgs e)
{
// display conflict type
Console.WriteLine(e.Conflict.Type);
// display error message
Console.WriteLine(e.Error);
}
}
}
As #JuneT notes this line is missing:
// subscribe for errors that occur when applying changes to the client
((SqlSyncProvider)syncOrchestrator.RemoteProvider).ApplyChangeFailed += new EventHandler<DbApplyChangeFailedEventArgs>(Program_ApplyChangeFailed);

Java API for Informatica

I am trying to use Java API to connect with informatica. I am tyring to run the samples at location
C:\Program Files\Informatica\PowerCenter8.6.1\MappingSDK\samples\src\com\informatica\powercenter\sdk\mapfwk\samples which uses com.informatica.powercenter.sdk.mapfwk.core.* libraries.
When I try to run CreateConnectionSample.java(simple connection to repository) I am getting exception.
code:
CachedRepositoryConnectionManager rpMgr = new CachedRepositoryConnectionManager(
new PmrepRepositoryConnectionManager());
Repository rep = new Repository();
RepoProperties repoProp = new RepoProperties();
repoProp.setProperty(RepoPropsConstant.PC_CLIENT_INSTALL_PATH,
"C:\\Program Files\\Informatica\\PowerCenter8.6.1\\client\\bin");
repoProp.setProperty(RepoPropsConstant.TARGET_REPO_NAME, "EDW_DEV_REPO");
repoProp.setProperty(RepoPropsConstant.REPO_SERVER_DOMAIN_NAME, "DOM_GWM_DEV01");
repoProp.setProperty(RepoPropsConstant.SECURITY_DOMAIN, "MSSB_INFA_DVLPR_DEV");
repoProp.setProperty(RepoPropsConstant.ADMIN_USERNAME, "Username");
repoProp.setProperty(RepoPropsConstant.ADMIN_PASSWORD, "Password");
repoProp.setProperty(RepoPropsConstant.TARGET_FOLDER_NAME,"CORE");
rep.setProperties(repoProp);
rep.setRepositoryConnectionManager(rpMgr);
ConnectionObject connObj = new ConnectionObject("Con", ConnectionAttributes.CONN_TYPE_RELATION);
rep.createConnection(connObj);
I am getting exception
com.informatica.powercenter.sdk.mapfwk.exceptions.ConnectionFailedException: Failed to list connections in PowerCenter Repository
Have anyone done this earlier? Can anyone help me to setup the Java API.
Well, this is really old, and hopefully you ended up getting connected using the SDK. Here's some recent code I put together to get a connection and query some stuff about workflows.
public static void main(String[] args) throws Exception {
if(System.getenv("INFA_DOMAINS_FILE") == null) // make sure .infa file exists
throw new Exception("INFA_DOMAINS_FILE path not set in environment variables.");
Repository rep = new Repository();
RepoConnectionInfo rci = new RepoConnectionInfo();
rci.setRepoServerHost("your host DNS name"); // set host URI
rci.setRepoServerPort("your host port number"); // host port
rci.setRepoServerDomainName("your-domain-name"); // repository domain name
rci.setTargetRepoName("your-repository"); // repository
rci.setSecurityDomain("e-directory"); // security type
rci.setAdminUsername("your-credentials"); // uid
rci.setAdminPassword(getPassword()); // pwd (stored in environment variable -- encoded so it's not cleartext)
rci.setPmrepCacheFolder("c:\\users\\your-credentials\\Informatica\\"); // some cache folder that must be set
rci.setPcClientInstallPath("C:\\Informatica\\9.0.1\\clients\\PowerCenterClient\\client\\bin\\");
rep.setRepoConnectionInfo(rci); // provide connection info to rep object
RepositoryConnectionManager repmgr = new PmrepRepositoryConnectionManager(); // set up repository connection manager
rep.setRepositoryConnectionManager(repmgr); // tell repository to use connection manager
System.out.println("Folders:");
System.out.println("===========================================================================");
List<Folder> folders = rep.getFolders();
for(Folder f: folders) { System.out.println(f);}
}

Getting started with embedded Jetty

I just got started with embedded jetty. I'm stuck at some error messages. It's simple and straightforward few lines code, which I found online and wanted to test out.
import org.jaxen.Context;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.ServletHolder;
public class Main {
public static void main(String[] args) throws Exception {
ServletHolder sh = new ServletHolder(ServletContainer.class);
sh.setInitParameter("com.sun.jersey.config.property.resourceConfigClass", "com.sun.jersey.api.core.PackagesResourceConfig");
sh.setInitParameter("com.sun.jersey.config.property.packages", "jerseyplusjetty");
Server server = new Server(80);
ServletContextHandler sch = new ServletContextHandler(server, "/");
sch.addServlet(sh, "/*");
server.start();
server.join();
}
}
I have all jetty jars in java build path. But I kept getting errors: The constructor ServletHolder(Class) is undefined, The constructor Server(int) is undefined, ServletContextHandler cannot be resolved to a type.
If I remove the parameter inside ServletHolder and Server, it stops complaining. e.g. if I have: ServletHolder sh = new ServletHolder(); Server server = new Server();
But that's not right. I read Jetty docs and ServletHolder class can take parameters. Am I missing something here?
Just FYI on embedded Jetty in general... I have created a github project that I humbly submit may cover most of the embedded jetty issues that keep cropping up.
I've got examples for AbstractHandlers, Servlets, Jersey Servlets, static files, webapps and what not. Still working on RoR and Sinatra, but will get there.
See https://github.com/ZenGirl/EmbeddedJettyRepository for details.
Anyone want to contribute, just ask.
The version of ServletHolder I have takes a String or a servlet in the constructor. So instead of doing
new ServletHolder(ServletContainer.class) you should do new ServletHolder(ServletContainer.class.getCanonicalName()) or new ServletHolder(new ServletContainer()).
ServletContainer is a strange name for a servlet, make sure it is actually a servlet.
Also, be aware that there are number of different versions of Jetty (you're using an old one because in the new one all the classes are in org.eclipse.jetty package), and it's easy to pick up example code that refers to a different version to the one you've got. I would get jetty 7.2.2 from maven and use the example code here.