Params from #ManagedService path are null - atmosphere

actually I would to retrieve two params from the #ManagedService path, but i get only null value.
The code is something like:
...
import org.atmosphere.config.service.PathParam;
import org.atmosphere.config.service.ManagedService;
import org.atmosphere.config.service.Singleton;
#Singleton
#ManagedService(path = "/chat/{myId}/{destId}")
public class Chat {
#PathParam("myId")
private String mittId;
#PathParam("destId")
private String destId;
#Ready
public void onReady(AtmosphereResource r) {
logger.info("User {} want to chat with {}", mittId,destId);
}
Debugging "mittId" and "destId" are null.
There's some error on the code or something that I forget?
Actually I'm using Atmosphere-runtime 2.3.0.
Thanks to anybody that will help!

The client is correct. I resolve removing #Singleton annotation. Now while I'm debugging I can see the value of the two params.

Either you are not sharing the enough or the original back-end code or your client application is calling the chat resource incorrectly.
I tested your example and both path parameters are populated.
Please have a look at the example in the Atmosphere Github page about the the multichatroom, especially the client implementation.

Related

Ethereum Chainlink HTTP Get not pinging my HTTP endpoint

I am attempting to have my Ethereum smart contract connect to an external HTTP endpoint using Chainlink. Following along with Chainlink's documentation (https://docs.chain.link/docs/advanced-tutorial/) I deployed this contract onto the Rinkeby testnet.
pragma solidity ^0.8.7;
import "github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/ChainlinkClient.sol";
// MyContract inherits the ChainlinkClient contract to gain the
// functionality of creating Chainlink requests
contract getHTTP is ChainlinkClient {
using Chainlink for Chainlink.Request;
bytes32 private thisDoesNotWork;
address private owner;
address private ORACLE_ADDRESS = 0x718Cc73722a2621De5F2f0Cb47A5180875f62D60;
bytes32 private JOBID = stringToBytes32("86b489ec4d84439c96181a8df7b22223");
string private url = "<myHTTPAddressAsString>";
// This endpoint URL is hard coded in my contract, and stored as a string (as in the example code).
// I control it and can have it reply with whatever I want, which might be an issue, returning data in a format that the oracle rejects
uint256 constant private ORACLE_PAYMENT = 100000000000000000;
constructor() public {
// Set the address for the LINK token for the network
setPublicChainlinkToken();
owner = msg.sender;
}
function requestBytes()
public
onlyOwner
{
Chainlink.Request memory req = buildChainlinkRequest(JOBID, address(this), this.fulfill.selector);
req.add("get", url);
sendChainlinkRequestTo(ORACLE_ADDRESS, req, ORACLE_PAYMENT);
}
function fulfill(bytes32 _requestId, bytes32 recVal)
public
recordChainlinkFulfillment(_requestId)
{
thisDoesNotWork = recVal;
}
function cancelRequest(
bytes32 _requestId,
uint256 _payment,
bytes4 _callbackFunctionId,
uint256 _expiration
)
public
onlyOwner
{
cancelChainlinkRequest(_requestId, _payment, _callbackFunctionId, _expiration);
}
// withdrawLink allows the owner to withdraw any extra LINK on the contract
function withdrawLink()
public
onlyOwner
{
LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress());
require(link.transfer(msg.sender, link.balanceOf(address(this))), "Unable to transfer");
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
// A helper funciton to make the string a bytes32
function stringToBytes32(string memory source) private pure returns (bytes32 result) {
bytes memory tempEmptyStringTest = bytes(source);
if (tempEmptyStringTest.length == 0) {
return 0x0;
}
assembly { // solhint-disable-line no-inline-assembly
result := mload(add(source, 32))
}
}
}
I found a node on the Chainlink market (https://market.link/jobs/529c7194-c665-4b30-8d25-5321ea49d9cc) that is currently active on rinkeby (according to Etherscan it has been active within the past 3 days and presumably still working).
I deploy the contract and fund the contract with LINK. I call the requestBytes() function through remix and everything works as expected. Metamask pays the gas, the LINK is removed from my contract, I get a transaction hash, and no errors.
However, my endpoint never logs a request attempt, the oracle never lists a transaction on its Etherscan page, and my data is not present.
I have attempted to use other jobs from the Chainlink market with similar outcomes.
I have also attempted to use other HTTP endpoints, like the ones from the Chainlink examples, with similar outcomes, however I doubt this is the issue, since it appears the HTTP request is never even getting called (as referenced by the fact that my HTTP endpoint does not log the request)
Without an error message, and being new to Web3 dev, I am not sure where to start debugging. I found this comment on Github: https://github.com/smartcontractkit/documentation/issues/513 and implemented the suggestion here without luck.
I also found this: Chainlink - Job not being fulfilled but this was not helpful either.
My current considerations for where the error might be:
The oracles are whitelisted and reject my request outright. Have considered creating my own node but want to avoid if possible at this stage.
I have an type error in how I am formatting the request in my contract, like the example in the GitHub exchange I found and referenced above.
EDIT: I am also open to other options beyond Chainlink to connect my contract to an HTTP GET endpoint, if anyone has any suggestions. Thanks!
I've been working on something similar recently and would suggest you try using the kovan network and the oracle that chainlink has there. Even more specifically, I think it would be a good idea to confirm you can get it working using the api, oracle, and jobid listed in the example on that page you are following... here:
https://docs.chain.link/docs/advanced-tutorial/#contract-example
Once you get that example working, then you can modify it for your usage. The jobid in that tutorial is for returning a (multiplied) uint256... which, for your API, I think is not what you want as you are wanting bytes32 it sounds like... so when you try to use it with your API that returns bytes32 the jobid would be: 7401f318127148a894c00c292e486ffd as seen here:
https://docs.chain.link/docs/decentralized-oracles-ethereum-mainnet/
Another thing that might be your issue, is your api. You say you control what it returns... I think it might have to return a response in bytes format, like Patrick says in his response (and his comments on his response) here:
Get a string from any API using Chainlink Large Response Example
Hope this is helpful. If you cannot get the example in the chainlink docs to work, let me know.

How to read data from PTC Windchill Info Engine using Java?

In the project I am assigned to do, it involves reading details of products from Info Engine using a Java Interface. How to do it? Suggest me tutorials or books or anything that helps me get started.
You can do that by implementing ComponentDataBuilder and that will return
a well populated IeTaskInfo object. It takes the action name as the constructor which gives information of the
task that need to be executed to get the data For example, the following code
snippet demonstrates the use of the “jca-Search” task .
public class MyDataBuilderWithIETask implements ComponentDataBuilder {
#Override
public Object buildComponentData(ComponentConfig config,
ComponentParams params) throws WTException {
//pass the task name as constructor
IeTaskInfo taskInfo = new IeTaskInfo("jca-Search");
……..
return taskInfo;
}
}
For more info please refer
Info*Engine User's Guide
Windchill Adapter Guide (Info*Engine)

how to dynamically register Feed Inbound Adapter in Spring Integration?

I'm trying to implement an RSS/Atom feed aggregator in spring-integration and I am primarily using the Java DSL to write my IntegrationFlow. A requirement of this aggregator is that feeds can be added / removed during runtime. That is to say, the feeds are not known at design time.
I found it simple to use the basic Feed.inboundAdapter() with a test url and extract the links out of the feed with a transformer and then pass it on to an outbound-file-adapter to save the links to a file. However, I have gotten very stuck when trying to read the (thousands) of feed urls from an inbound-file-adapter run the file through a FileSplitter and then pass each resulting Message<String> containing the feed url to then register a new Feed.inboundAdapter(). Is this not possible with the Java DSL?
Ideally I would love it if I could do the following:
#Bean
public IntegrationFlow getFeedsFromFile() throws MalformedURLException {
return IntegrationFlows.from(inboundFileChannel(), e -> e.poller(Pollers.fixedDelay(10000)))
.handle(new FileSplitter())
//register new Feed.inboundAdapter(payload.toString()) foreach Message<String> containing feed url coming from FileSplitter
.transform(extractLinkFromFeedEntry())
.handle(appendLinkToFile())
.get();
}
Though after reading through the spring integration java DSL code multiple times (and learning a tonne of stuff along the way) I just can't see that it's possible to do it this way. So... A) is it? B) should it be? C) Suggestions?
It almost feels like I should be able to take the output of .handle(new FileSplitter()) and pass that into .handleWithAdapter(Feed.inboundAdapter(/*stuff here*/)) but the DSL only references outbound-adapters there. Inbound adapters are really just a subclass of AbstractMessageSource and it seems the only place you can specify one of those is as an argument to the IntegrationFlows.from(/*stuff here*/) method.
I would have thought it would be possible to take the input from a file, split it line by line, use that output to register inbound feed adapters, poll those feeds, extract the new links from feeds as they appear and append them to a file. It appears as though it's not.
Is there some clever subclassing I can do to make this work??
Failing that... and I suspect this is going to be the answer, I found the spring integration Dynamic Ftp Channel Resolver Example and this answer on how to adapt it dynamically register stuff for the inbound case...
So is this the way to go? Any help/guidance appreciated. After pouring over the DSL code and reading documentation for days, I think I'll have a go at implementing the dynamic ftp example and adapting it to work with FeedEntryMessageSource... in which case my question is... that dynamic ftp example works with XML configuration, but is it possible to do it with either Java config or the Java DSL?
Update
I've implemented the solution as follows:
#SpringBootApplication
class MonsterFeedApplication {
public static void main(String[] args) throws IOException {
ConfigurableApplicationContext parent = SpringApplication.run(MonsterFeedApplication.class, args);
parent.setId("parent");
String[] feedUrls = {
"https://1nichi.wordpress.com/feed/",
"http://jcmuofficialblog.com/feed/"};
List<ConfigurableApplicationContext> children = new ArrayList<>();
int n = 0;
for(String feedUrl : feedUrls) {
AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext();
child.setId("child" + ++n);
children.add(child);
child.setParent(parent);
child.register(DynamicFeedAdapter.class);
StandardEnvironment env = new StandardEnvironment();
Properties props = new Properties();
props.setProperty("feed.url", feedUrl);
PropertiesPropertySource pps = new PropertiesPropertySource("feed", props);
env.getPropertySources().addLast(pps);
child.setEnvironment(env);
child.refresh();
}
System.out.println("Press any key to exit...");
System.in.read();
for (ConfigurableApplicationContext child : children) {
child.close();
}
parent.close();
}
#Bean
public IntegrationFlow aggregateFeeds() {
return IntegrationFlows.from("feedChannel")
.transform(extractLinkFromFeed())
.handle(System.out::println)
.get();
}
#Bean
public MessageChannel feedChannel() {
return new DirectChannel();
}
#Bean
public AbstractPayloadTransformer<SyndEntry, String> extractLinkFromFeed() {
return new AbstractPayloadTransformer<SyndEntry, String>() {
#Override
protected String transformPayload(SyndEntry payload) throws Exception {
return payload.getLink();
}
};
}
}
DynamicFeedAdapter.java
#Configuration
#EnableIntegration
public class DynamicFeedAdapter {
#Value("${feed.url}")
public String feedUrl;
#Bean
public static PropertySourcesPlaceholderConfigurer pspc() {
return new PropertySourcesPlaceholderConfigurer();
}
#Bean
public IntegrationFlow feedAdapter() throws MalformedURLException {
URL url = new URL(feedUrl);
return IntegrationFlows
.from(s -> s.feed(url, "feedTest"),
e -> e.poller(p -> p.fixedDelay(10000)))
.channel("feedChannel")
.get();
}
}
And this works IF and only IF I have one of the urls defined in application.properties as feed.url=[insert url here]. Otherwise it fails telling me 'unable to resolve property {feed.url}'. I suspect what is happening there is that the #Beans defined in DynamicFeedAdapter.java all get singletons eagerly initialized, so aside from the beans being manually created in our for loop in the main method (which work fine because they have feed.url property injected) we have a stray singleton that has been eagerly initialized and if there is no feed.url defined in application.properties then it can't resolve the property and everything goes bang. Now from what I know of Spring, I know it should be possible to #Lazy initialize the beans in DynamicFeedAdapter.java so we don't wind up with this one unwanted stray singleton problem-child. The problem is now...if I just mark the feedAdapter() #Lazy then the beans never get initialized. How do I initialize them myself?
Update - problem solved
Without having tested it, I think the problem is that boot is finding
the DynamicFeedAdapter during its component scan. A simple solution is
to move it to a sibling package. If MonsterFeedApplication is in
com.acme.foo, then put the adapter config class in com.acme.bar. That
way, boot won't consider it "part" of the application
This was indeed the problem. After implementing Gary's suggestion, everything works perfect.
See the answer to this question and its follow up for a similar question about inbound mail adapters.
In essence, each feed adapter is created in a child context that is parameterized.
In that case the child contexts are created in a main() method but there's no reason it couldn't be done in a service invoked by .handle().

Determine runmode in Adobe CQ

How do I programmatically know which run-mode the instance is running? I created a custom tag that provides the config depending on the instance run-mode, but I can not determine the current run-mode.
I found a method that returns a list of run-mods instance:
SlingSettings settings = ...get from BundleContext...
Set<String> currentRunModes = settings.getRunModes();
But I can not get the objects SlingSettings or BundleContext. How can I get these objects or perhaps there is another way to get the current run-mode?
SlingSetttings is the right way - If it's from Java the simplest way to get it is with an SCR #Reference annotation in a class that's an SCR #Component, saves you from having to go through BundleContext.
If it's from a Sling script, you can use sling.getService(....) to get the SlingSettings.
Note that the cases where you need to read the run modes are rare, usually you'd rather setup your OSGi configurations to depend on the run modes and have the OSGi components modify their behavior based on that.
Finally I decided to use global.jsp, write run-modes in the page context and get it in my class:
<%
pageContext.setAttribute("runModes", sling.getService(SlingSettingsService.class).getRunModes().toString());
%>
import java.util.Set;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.apache.sling.settings.SlingSettingsService;
public class myClass {
public static Set<String> getRunModes() {
BundleContext bundleContext = FrameworkUtil.getBundle(myClass.class).getBundleContext();
ServiceReference serviceReference = bundleContext.getServiceReference(SlingSettingsService.class.getName( ));
SlingSettingsService slingSettingsService = (SlingSettingsService)bundleContext.getService(serviceReference);
return slingSettingsService.getRunModes();
}
}
#Reference
RunMode runmode;
or
sling.getService( RunMode.class )
and call
getCurrentRunModes(); //returns String[]
If you're using Sightly and working with a class that extends WCMUsePojo
slingSettings =this.getSlingScriptHelper().getService(SlingSettingsService.class);
Set<String> runmodes = slingSettings.getRunModes();
As Bertrand Delacretaz said it is the right way to check whether instance is Author or Publish.
In jsp or java you could check like
import org.apache.sling.settings.SlingSettingsService
Set<String> runModes = sling.getService(SlingSettingsService.class).getRunModes();
if (runModes.contains("author")) {
}
Another way is using
if (mode == WCMMode.EDIT)
{
}
But this approach will fail in case of Preview mode and wouldn't work.
You can also try this:
RunModeService runModeService = getSlingScriptHelper().getService(RunModeService.class);
author = runModeService.isActive("author");

MultiPart Request RenameFilePolicy

I am trying to avoid some naming conflicts in my uploaded files (I used com.oreilly.servlet.MultipartRequest ).
At this moment my constructor looks like this:
MultipartRequest multi = new MultipartRequest(request, uploadPath);
I would like to implement the constructor with FileRenamePolicy in order to rename my file with a value taken from a form (something like request.getParameterValue("title");
I think I should use the foloowing constructor? But I don't know how to set the "policy" paramter
MultipartRequest(javax.servlet.http.HttpServletRequest request,
java.lang.String saveDirectory,
int maxPostSize,
java.lang.String encoding,
FileRenamePolicy policy)
Do you have any suggestions?
Thanks!
You should implement a custom FileRenamePolicy which gives you the File appending the title sent along with the request.
Here is what you are looking for:
private static class MyTitleRenamePolicy extends FileRenamePolicy {
java.io.File rename(java.io.File f) {
return new File(f.getParentFile(),
rename.getName() + "_"+ request.getParameter("title"));
}
}
new MultipartRequest(request, saveDirectory, maxPostSize, encoding,
new MyTitleRenamePolicy(request));

Resources