From the business prespective, here's the problem
We have a number of shared folders that people use, let's call it //shared/the/drive. However, our server might know this shared drive as some other name, perhaps //ir83pn3br8mwhonamesthesethingsanyway/the/drive since the networking group insists on having incredibly messed up server names. For most of the servers, it works just fine to use the simple name, but on this one, it's just not working right. So the bandaid for our problem is, in our code, to just be like "Oh you're using shared - we'll replace that with stupid name from networking.
Okay - now on to the more technical side of things:
I have a FileItem (Apache commons FileUpload module) object that might have a name //shared/the/drive/stuff/plans.doc. I need to create a FileItem that references //stupidname/the/drive/stuff/plans.doc. What should I do?
Should I edit the request object in the JSP? That sounds like a bad idea.
Should I use reflection to edit the FileItem object? That sounds like an even worse idea.
I'm not a front end guy (note which tags I have votes in... haha), really... more of a server dude... this just got dropped onto my plate. Is it possible to intercept the text box before it gets to the request, moving the change to the client side?
I can't possibly have been the first person to come across this problem. I'm not looking for code necessarily (would I mind? No I wouldn't.) but a general approach of both what will work, and/or how this sort of thing (changing what a user inputs) is handled in a 'best practicey' kind of way is most welcome.
Its not uncommon when dealing with distributed file systems to have a "fake path" which the user sees and deals with and a backend path which represent the actual node that allows you to manipulate the file in context of the request you receive.
Every page you hit on the web is not represented by the physical URL you type into the browser. Files live on CDNs, in CMS systems, are dynamically created out of databases ....whatever.
Theres no need to hack on any objects. You just wrap them with another object that contains their transient properties such as where Im going to access that file THIS time.
Related
I'm developing this JavaEE REST microservice oriented CQRS + EventSourcing app, I have this entity (Artwork) with many fields and I have to record each update to this entity according to EventSourcing pattern (basically each update creates a new event, the artwork is then rebuild using these events).
My approach basically works, but I'm stuck with a "compliance" towards HTTP standards, basically I want to avoid a "generic" update in which you update the whole entity because it will be a mess to handle each single field update (and consequent event generation).
So this is what I did.
Let's say that I have this entity:
public entity{
int id;
String field1;
String field2;
...
Then I created as many requests as many fields I have to update (not all fields can be updated, such as the ID)
public field1UpdateRequest{
field1 newvalue;
}
and the same for field 2.
These updated are handled using a PUT request, when such a request arrives, it is handled by something like this:
HTTP → Controller→ Service → (DAOS etc.)
So in the controller class I have a PUT http://...//updatefield1 method that accepts field1UpdateRequest objects.
My question is:
Is this right to do? How can I explain that this is right (if it is)? should these requests be PATCH more than PUT? Should a generic PUT request also be included? (Even if I'm scared that this will make the event sourcing part more difficult)?
In a CQRS spproach, it's important to remember that the C stands for Command. Every request to your "write-side" is thus a command. A generic "here is the new value for this resource" request (which is what REST tends to lead to) can be interpreted as a "use this value henceforth" command, but it is a bit of an impedance mismatch with CQRS, because it's a fairly anemic command. There are definitely cases where having that in an API can be called for (and if it's an exceptionally rare request, you may even be able to get away with modeling it as a single "new beginning" event rather than teasing out finer-grained events; this has the cost of shifting some complexity out to consumers of the events).
With that in mind, an alternative approach that updates parts of an object is a little more of a fit with CQRS (though in this case, you are shifting some complexity to requestor, at least if that requestor wants to do wholesale updates). HTTP PUTsounds proper to me: the command is "use this value for this field/component of the entity".
That said, an even more CQRSy API would instead focus on the higher-level activities which motivate a change to the entity. For instance if you're tracking the current owner of the artwork as of when it was sold, you might have a currentOwner and a currentOwnerAcquired field in your artwork entity. When recording a sale, you would want to update both, so a POST /artworks/{artworkId}/transferOwnership endpoint taking something like
{
"transferor": "Joe Bloggs",
"transferee": "Jack Schmoe",
"date": "2021-12-24T00:00:01Z"
}
would allow the update to be a single transaction and allow you to encode the "why" as well as the "what" in your events (which is an advantage of event sourcing).
So in the controller class i have a PUT http://...//updatefield1 method that accepts field1UpdateRequest objects.
Is this right to do?
It might be, but it probably isn't.
Here's the key idea: your REST API is a facade; it supports the illusion that your server is stores and produces documents. In other words, your providing an interface to your data that makes it look like every other site on the web.
The good news: when you do that, you get (for free!) the benefits of a bunch of general purpose work that has already been done for you.
But the cost (of these things that you get for free) is that - for everything to "just work", you need to handle the impedance mismatch between HTTP (which is based on an idiom of documents) and your domain model.
So I send to you messages to "edit your documents", and you in turn figure out how to translate those messages into commands for your domain model.
In HTTP, both PUT and PATCH have remote authoring semantics. Both of those messages mean "make your copy of the document look like my copy". They are the flavor of HTTP messages you would use to (for example) edit the title of an HTML document on your web server.
The semantics are fundamentally anemic. My message tells you how I want your copy of the document to look, your server is responsible for figuring out how to achieve that.
And that's fine when you are working with documents, or using documents as a facade in front of a data model. But matching remote authoring requests with a domain model are a lot harder.
(Recommended reading: Greg Young 2010 on task based user interfaces).
In the case of a domain model, you normally want to send to the server a representation of a command message. HTTP really wants you to deal with command messages in one of two ways:
treat the command message as a document/resource of its own, to be stored on the server (the changes to the domain model are a side effect of storing a new command message)
POST the command message to the resource most directly impacted by the change.
(See Fielding, 2009; it is okay to use POST).
In both cases, the HTTP application itself knows nothing about what's going on at the domain level, it is only concerned with the transfer of documents over the network.
HTTP doesn't really place any constraints on your resource model - if you want to publish all of your information in one document, that's fine. If you want to distribute your information across many documents, that's also fine.
So taking a single entity in your domain, and distributing its information across many resources is fine.
BUT: remember caching. HTTP has simple rules for automatically invalidating previously cached responses; separating the resource you use for reading information from the resource that you use for editing information makes caching harder (caution: caching is already one of the two hard problems).
In other words: trade offs.
I just want to know the high level steps of the process. Here's my thought on the process:
Assumption: the API returns JSON format
Check the API document to see the structure of the returned JSON
Create a corresponding Java class (ex: Employee)
Make Http call to the endpoint to get the JSON response
Using some JSON library (such as GSON, Jackson) to unmarshall the JSON string to Employee object.
Manipulate the Employee object
However, what if the API returned JSON is changed? it's really tedious task to exam the JSON string every now and then to adjust the corresponding Java class.
Can anyone help me out with this understanding. Thanks
You describe how to consume a json over http API, which is fine since most of the APIs out there are just that. If you are interested in consuming Restful HTTP resources however, one way would be:
Check the API documentation, aka. the media-types that your client will need to support in order to communicate with its resources. Some RESTafarians argue that all media-types should be standardized, so all clients could potentially support them, but I think that goes a bit far.
Watch out for link representations, and processing logic. media-types do not only describe the format of the data, but also how to process them. How to display it if its an image, how to run code that might be part of the message, how to layout onto the screen, how to use embedded controls like forms, etc.
Create corresponding Java classes. If the resources "only" describe data (which they usually do in API context), then simple Java classes will do, otherwise more might be needed. For example: can the representation contain JavaScript to run on the client? You need to embed a JavaScript engine, and prepare your class to do just that.
Make call to a bookmarked URI if you have it. There should be no hardcoded SOAP-like "endpoint" you call. You start with bookmarks and work your way to the state your client need to be in.
Usually your first call goes to the "start" resource. This is the only bookmark you have in the beginning. You specify the media-types you support for this resource in the Accept header.
You then check whether the returned Content-Type matches one of your accepted media-types (remember, the server is free to ignore your preferences), and then you process the returned representation according to its rules.
For example you want to get all the accounts for customer 123456 for which you don't yet have a bookmark to. You might first GET the start resource for account management. The processing logic there might describe a link to go to for account listings. You follow the link. The representation there might give you a "form" in which you have to fill out the customer number and POST. Finally, you get your representation of the account list. You may at this point bookmark the page, so you don't have to go through the whole chain the next time.
Process representation. This might involve displaying, running, or just handing over the data to some other class.
Sorry for the long post, slow day at work :) Just for completeness, some other points the client needs to know about: caching, handling bookmarks (reacting to 3xx codes), following links in representations.
Versioning is another topic you mention. This is a whole discussion onto itself, but in short: some people (myself included) advocate versioning the media-type. Non-backwards compatible changes simply change the media type's name (for example from application/vnd.company.customer-v1+json, to application/vnd.company.customer-v2+json), and then everything (bookmarks for example) continues to work because of content negotiation.
There are many ways to consume RESTful APIs.
Typically, you need to know what version of the API you are going to use. When the API changes (i.e. a different version is exposed) you need to decide if the new functionality is worth migrating your application(s) to the latest and greatest or not...
In my experience, migrating to a new API always requires some effort and it really depends on the value of doing so (vs. not doing it) and/or whether the old API is going to be deprecated and/or not supported by the publisher.
Particularly, what are all the dots and numbers at the end for.
Here is an example:
https://www.google.com/search?site=&tbm=isch&source=hp&biw=1366&bih=673&q=kale&oq=kale&gs_l=img.3..0l10.403.1120.0.1352.4.4.0.0.0.0.407.543.0j1j4-1.2.0....0...1ac.1.32.img..2.2.542.vC-f2Kfx-2E
It is a GET variables value, but why such a strange un-human readable syntax?
I assume they are using PHP or Java on the back-end.
What you are seeing is internal computer data, not exactly intended for normal human consumption, but there for a good reason. Also perhaps you are thinking, why would anyone want these ugly internal details displayed on the average user's screen?
When HTTP was invented the thought was that GET requests should be stateful, in other words, if I copy a URI from my browser and email it to you, and you browse to it, then you should see exactly what I saw. To make this work the GET data needed to be in the URI and not hidden from view. Thus the dirty details you are seeing. Back in the day they were thinking of simple GET queries, for example: http://www.somedomain.com/Search?Find=FooBar
However, as software has evolved more data needs to be passed with GET requests and unfortunately it is all visible in the URI. (Note that this also becomes a minor security hole because the average user can see some of the internals of web page production and easily tamper with it.)
What is needed is a hidden data passing method for GET type queries to clean up URIs when it is not necessary for these details to be present. A proposal for such an improvement to HTTP is in the process of being considered. It would involve adding a new method to HTTP similar to GET but with hidden data passing like POST.
So here's my project:
I am building a central interface/dashboard to present the test data for several test types of multiple product versions. We're using TestNG on our massive product, and while not enough tests are being written, that's a discussion for another topic. Here's what the directory structure looks like:
Filesystem/productVersion+testType/uniqueDateAndBuildID/testng-results.xml
That results.xml file contains tags with child test tags, which correspond to a filesystem directory and then xml files containing actual test case results (pass, fail, etc)
The XML parsing and filesystem traversal is all well and good/reliable.
Flow of control:
Client accesses main page --> server opens properties file --> server checks for web server property (either Websphere or Tomcat, if I'm working locally) --> server sets bunch of constants based on that. Constants include: root filesystem directory, filesystem separator (translation), "like types (basically same tests on different platforms)", and a base URL to append onto. --> server then reads properties file some more and does all of its XML processing. Results are cached in memory as well as to the filesystem using ObjectOutputStream. --> A big list of results is sent back to the client to do the UI processing/display.
Here's where I run into a problem: I can't access those Global variables (contained/set in a Globals class...bad I know :-/ ) back on the client, even though they're in the shared folder. If you're wondering why I can't just load the properties again, it's because the client is GWT-ified Javascript which doesn't include File(). So my next thought, having done a little bit of upper level Java reading was to maybe use a Globals singleton object and pass that back too..but it seems like that's just as bad if not impossible. Suggestions here would be great.
This whole thing is pretty tightly coupled, something my previous Java education hadn't really gotten into yet. And since this is just an internal portal for devs to check, there doesn't seem to be much of a point in actually testing my code. As long as it displays correctly, logs properly, and handles errors gracefully, right? All in all it's <15 classes, so it's not really a big big deal I guess. Should I refactor to clean it all up and make it "better Java", comment everything to clearly delineate flow of control, or not worry too much about it because it's small? I know in the future to think more about things before I design them, but I really didn't know a large amount of the higher Java principles I've been exposed to since starting.
edit after doing a bit of thinking, came up with a possible workaround. What about, instead of passing back only a list of results, I passed back some other custom list implementation that included a globals 'header' object? I could preserve state.
A simple solution would be the Dictionary class:
Provides dynamic string lookup of
key/value string pairs defined in a
module's host HTML page. Each unique
instance of Dictionary is bound to a
named JavaScript object that resides
in the global namespace of the host
page's window object. The bound
JavaScript object is used directly as
an associative array.
You just need to add some dynamic content to your host HTML page - make the server print the values read from the properties file in the form of a JavaScript object:
var GlobalProperties = {
property1: "value1",
property2: "value2"
};
Then, use Dictionary in your code to read those values:
Dictionary globalProperties = Dictionary.getDictionary("GlobalProperties");
String property1 = globalProperties.get("property1");
PS: If you are looking for good ideas/advices on how to make your code less coupled -> more testable, I'd recommend Misko Hevery's blog. He's got many interesting posts, like why singletons are usually bad (global state, not the pattern itself). But most importantly - it has the awesome guide to writing testable code (some guidelines used internally in Google).
You could pass those Global variables using a simple object with a HashMap thought a GWT-RPC call or just include this Hashmap with the result you already retrieve in the first place (along the "big list of results [that] is sent back to the client to do the UI processing/display.")
You can't access serverside singletons from the compiled javascript.
You have two options basically. You can make a Serializable class in the client code, that represents the global variables, or pass your global variables object, but this is a rather inefficient solution.
The simplest is to use a HashMap<String, String> in a serializable object, which you can retrieve with an RPC call:
public class GwtGlobalVariables implements Serializable {
private HashMap<String, String> map = new HashMap<String, String>();
public void put(// a delegate put method of choice
public void setMap() // a getter / setter for the map if you need it
}
Ensure the class is within a GWT module's source folders, i.e. in the same place as your entry point maybe.
Fill the map out with the values needed, pass it through rpc and you have it in your client side code.
I find myself with a need for a java utility for taking a fully-qualified hostname, and producing the domain name from that.
In the simple case, that means turning host.company.com into company.com, but this gets rapidly more complicated with host.subdomain.company.com, for example, or host.company.co.uk, where the meaning of "domain name" gets a bit fuzzy. Throw in complications with the definition of SLD and ccSLD, and it gets messy.
So my question is whether there's a 3rd-party library out there that understands these things and can give me sensible interpreations.
Mozilla regularly maintains the rules that it uses in its browser for cookie security in a format that can be parsed and used by others:
http://publicsuffix.org/
Searching Google, there are probably Java libraries that can parse the list, but I don't know the quality of any of them.
I don't think such a thing exists, since it's an adminstrative rather than technical issue, and a very multi-lateral one, at that.
If you end up rolling your own, this page on the Mozilla wiki looks like a good starting point, with lots of references. Looks like a major headache though. Just look at the rules for Japan. Ouch.
Not sure if it's for the same purpose, I do something similar in my code. When I set cookies, I want to set the domain as close to top as possible so I need to find the domain one-level lower than a public suffix. For example, the highest domain you can set cookie for host.div.example.com is .example.com. For host.div.example.co.jp is .example.co.jp.
Unfortunately, the code is not in the public domain. It's very easy to do. I basically use following 2 classes from Apache HttpClient 4,
org.apache.http.impl.cookie.PublicSuffixFilter
org.apache.http.impl.cookie.PublicSuffixListParser
I forgot the exact reason but we had to make some very minor tweaks. You just walk the domain from top to bottom, first valid cookie domain is what you need.
You need to download the public suffix list from here and include it in your JAR,
http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/src/effective_tld_names.dat?raw=1