NetworkInterface.GetIsNetworkAvailable() versus DeviceNetworkInformation.IsNetworkAvailable - windows-phone-7.1

DeviceNetworkInformation.IsNetworkAvailable
// Summary:
// Gets a value that indicates whether the network is available.
//
// Returns:
// true if there is at least one network interface available; otherwise, false.
public static bool IsNetworkAvailable { get; }
NetworkInterface.GetIsNetworkAvailable()
// Summary:
// Indicates whether any network connection is available.
//
// Returns:
// true if a network connection is available; otherwise, false.
[SecuritySafeCritical]
public static bool GetIsNetworkAvailable();
Are these identical?

Microsoft wants you to use DeviceNetworkInformation.IsNetworkAvailable
NetworkInterface is in System.Net where as DeviceNetworkInformation is in Microsoft.Phone.Net.NetworkInformation.
The DeviceNetworkInformation.IsNetworkAvailable might map to NetworkInterface.GetIsNetworkAvailable() internally, but you should always use DeviceNetworkInformation.IsNetworkAvailable because it's made for the phone (and have a cleaner API).
And as pointed out by Matthieu, DeviceNetworkInformation.IsNetworkAvailable is apparently new in 7.1 (Mango).

Related

Bug trying to use .call with non-native ERC20 token in Solidity

I have this function called "exchangeCall" in my contract with which I can send an amount of its native ETH token ("values"), data in bytes ("callData") and an estimated gas ("estimatedGas") towards another contract ("target"). The purpose is to send the byte data ("callData"), which already contains a previously defined series of steps.
This script works perfectly when I try (for example) to exchange through the Uniswap contract, ETH (native token) for UNI (or another token).
However, when I try to do it the other way around by exchanging any token other than ETH for another one it generates an error.
In the following video you can find a more specific explanation through an example:
Videolink -> https://drive.google.com/file/d/1ujP5Q_-_PHpkDNb1Jeldo1HveReWZUMT/view
For my case, it is important that this code is made only in solidity (not web3 or similar).
I have already checked the permissions so that the non-native token can be used by the contract, it can be done with the other auxiliary functions present in the contract or through the IERC20 which is also invoked there.
I hope someone can help me, and I share the script code.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
pragma experimental ABIEncoderV2;
import {IERC20} from "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol";
contract SimpleExchange {
address payable owner;
// SOME TOKENS FOR TEST
address private immutable uniAddress =
0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984; // UNI TOKEN
address private immutable usdcAddress =
0xA2025B15a1757311bfD68cb14eaeFCc237AF5b43; // USDC TOKEN
address dexContractAddress =
0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45; // Contrato Objetivo
// FUNCTION FOR EXCHANGE
function exchangeCall(address target, bytes memory callData, uint values, uint estimatedGas) public payable returns (uint256 blockNumber) {
blockNumber = block.number;
(bool success, bytes memory ret) = target.call{value:values,gas:estimatedGas}(callData);
require(success);
}
//OPTIONAL FUNCTIONS FOR DEVELOPMENT TESTS
function approveUSDC(uint256 _amount) external returns (bool) {
return IERC20(usdcAddress).approve(dexContractAddress, _amount);
}
function allowanceUSDC() external view returns (uint256) {
return IERC20(usdcAddress).allowance(address(this), dexContractAddress);
}
function approveUNI(uint256 _amount) external returns (bool) {
return IERC20(uniAddress).approve(dexContractAddress, _amount);
}
function allowanceUNI() external view returns (uint256) {
return IERC20(uniAddress).allowance(address(this), dexContractAddress);
}
function getBalance(address _tokenAddress) external view returns (uint256) {
return IERC20(_tokenAddress).balanceOf(address(this));
}
function transfer(address _tokenAddress, address receiverAddr, uint receiverAmnt) public payable{
IERC20 token = IERC20(_tokenAddress);
token.transfer(receiverAddr, receiverAmnt);
}
function transferFrom(address sender, address recipient, uint256 amount,address token) external returns (bool){
IERC20(token).transferFrom(sender,recipient,amount);
return true;
}
function withdraw(address _tokenAddress) external {
IERC20 token = IERC20(_tokenAddress);
token.transfer(msg.sender, token.balanceOf(address(this)));
}
// Function to receive Ether. msg.data must be empty
receive() external payable {}
// Fallback function is called when msg.data is not empty
fallback() external payable {}
}

How chain indefinite amount of flatMap operators in Reactor?

I have some initial state in my application and a few of policies that decorates this state with reactively fetched data (each of policy's Mono returns new instance of state with additional data). Eventually I get fully decorated state.
It basically looks like this:
public interface Policy {
Mono<State> apply(State currentState);
}
Usage for fixed number of policies would look like that:
Flux.just(baseState)
.flatMap(firstPolicy::apply)
.flatMap(secondPolicy::apply)
...
.subscribe();
It basically means that entry state for a Mono is result of accumulation of initial state and each of that Mono predecessors.
For my case policies number is not fixed and it comes from another layer of the application as a collection of objects that implements Policy interface.
Is there any way to achieve similar result as in the given code (with 2 flatMap), but for unknown number of policies? I have tried with Flux's reduce method, but it works only if policy returns value, not a Mono.
This seems difficult because you're streaming your baseState, then trying to do an arbitrary number of flatMap() calls on that. There's nothing inherently wrong with using a loop to achieve this, but I like to avoid that unless absolutely necessary, as it breaks the natural reactive flow of the code.
If you instead iterate and reduce the policies into a single policy, then the flatMap() call becomes trivial:
Flux.fromIterable(policies)
.reduce((p1,p2) -> s -> p1.apply(s).flatMap(p2::apply))
.flatMap(p -> p.apply(baseState))
.subscribe();
If you're able to edit your Policy interface, I'd strongly suggest adding a static combine() method to reference in your reduce() call to make that more readable:
interface Policy {
Mono<State> apply(State currentState);
public static Policy combine(Policy p1, Policy p2) {
return s -> p1.apply(s).flatMap(p2::apply);
}
}
The Flux then becomes much more descriptive and less verbose:
Flux.fromIterable(policies)
.reduce(Policy::combine)
.flatMap(p -> p.apply(baseState))
.subscribe();
As a complete demonstration, swapping out your State for a String to keep it shorter:
interface Policy {
Mono<String> apply(String currentState);
public static Policy combine(Policy p1, Policy p2) {
return s -> p1.apply(s).flatMap(p2::apply);
}
}
public static void main(String[] args) {
List<Policy> policies = new ArrayList<>();
policies.add(x -> Mono.just("blah " + x));
policies.add(x -> Mono.just("foo " + x));
String baseState = "bar";
Flux.fromIterable(policies)
.reduce(Policy::combine)
.flatMap(p -> p.apply(baseState))
.subscribe(System.out::println); //Prints "foo blah bar"
}
If I understand the problem correctly, then the most simple solution is to use a regular for loop:
Flux<State> flux = Flux.just(baseState);
for (Policy policy : policies)
{
flux = flux.flatMap(policy::apply);
}
flux.subscribe();
Also, note that if you have just a single baseSate you can use Mono instead of Flux.
UPDATE:
If you are concerned about breaking the flow, you can extract the for loop into a method and apply it via transform operator:
Flux.just(baseState)
.transform(this::applyPolicies)
.subscribe();
private Publisher<State> applyPolicies(Flux<State> originalFlux)
{
Flux<State> newFlux = originalFlux;
for (Policy policy : policies)
{
newFlux = newFlux.flatMap(policy::apply);
}
return newFlux;
}

Spring Cloud AWS Issue with setting manual acknowledge of SQS message

I'm trying to implement logic with manual deleting of AWS SQS message using spring-cloud-aws-messaging. This feature was implemented in scope of this ticket from the example in tests
#SqsListener(value = "queueName", deletionPolicy = SqsMessageDeletionPolicy.NEVER)
public void listen(SqsEventDTO message, Acknowledgment acknowledgment) {
LOGGER.info("Received message {}", message.getFoo());
try {
acknowledgment.acknowledge().get();
} catch (InterruptedException e) {
LOGGER.error("Opps", e);
} catch (ExecutionException e) {
LOGGER.error("Opps", e);
}
}
But faced with the unexpected exception
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance oforg.springframework.cloud.aws.messaging.listener.Acknowledgment(no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
Solution with SqsMessageDeletionPolicy.ON_SUCCESS works but I want to avoid throwing an exception.
What have I missed in the configuration?
It took some fiddling around and trying different things from other SO answers.
Here is my code and I'll try to explain as best I can. I'm including everything that I'm using for my SQS consumer.
My config class is below. Only not-so-obvious thing to note below is the converter and resolver objects instantiated in the queueMessageHandlerFactory method. The MappingJackson2MessageConverter (in case it isn't obvious from the oh-so-obvious class name) class handles the deserialization of the payload from SQS.
It's also important that the strict content type match be set to false.
Also, the MappingJackson2MessageConverter allows you to set your own Jackson ObjectMapper, however if you do that you will need to configure it as follows:
objectMapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
You may not want to do that, so you can leave it null and it will create its own ObjectMapper.
I think the rest of the code is pretty self-explanatory...? Let me know if not.
One difference between our use-cases, it looks like you're mapping your own custom object (SqsEventDTO) and I assume that's working? In that case, I don't think you will need the MappingJackson2MessageConverter, but I could be wrong.
#Configuration
public class AppConfig {
#Bean
#Primary
public QueueMessageHandler queueMessageHandler(#Autowired QueueMessageHandlerFactory queueMessageHandlerFactory) {
return queueMessageHandlerFactory.createQueueMessageHandler();
}
#Bean
#Primary
public QueueMessageHandlerFactory queueMessageHandlerFactory(#Autowired AmazonSQSAsync sqsClient) {
QueueMessageHandlerFactory factory = new QueueMessageHandlerFactory();
factory.setAmazonSqs(sqsClient);
MappingJackson2MessageConverter messageConverter = new MappingJackson2MessageConverter();
messageConverter.setSerializedPayloadClass(String.class);
//set strict content type match to false
messageConverter.setStrictContentTypeMatch(false);
// Uses the MappingJackson2MessageConverter object to resolve/map
// the payload against the Message/S3EventNotification argument.
PayloadArgumentResolver payloadResolver = new PayloadArgumentResolver(messageConverter);
// Extract the acknowledgment data from the payload's headers,
// which then gets deserialized into the Acknowledgment object.
AcknowledgmentHandlerMethodArgumentResolver acknowledgmentResolver = new AcknowledgmentHandlerMethodArgumentResolver("Acknowledgment");
// I don't remember the specifics of WHY, however there is
// something important about the order of the argument resolvers
// in the list
factory.setArgumentResolvers(Arrays.asList(acknowledgmentResolver, payloadResolver));
return factory;
}
#Bean("ConsumerBean")
#Primary
public SimpleMessageListenerContainer simpleMessageListenerContainer(#Autowired AmazonSQSAsync amazonSQSAsync, #Autowired QueueMessageHandler queueMessageHandler,
#Autowired ThreadPoolTaskExecutor threadPoolExecutor) {
SimpleMessageListenerContainer smlc = new SimpleMessageListenerContainer();
smlc.setWaitTimeOut(20);
smlc.setAmazonSqs(amazonSQSAsync);
smlc.setMessageHandler(queueMessageHandler);
smlc.setBeanName("ConsumerBean");
smlc.setMaxNumberOfMessages(sqsMaxMessages);
smlc.setTaskExecutor(threadPoolExecutor);
return smlc;
}
#Bean
#Primary
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setAllowCoreThreadTimeOut(coreThreadsTimeout);
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setMaxPoolSize(maxPoolSize);
executor.setKeepAliveSeconds(threadTimeoutSeconds);
executor.setThreadNamePrefix(threadName);
executor.initialize();
return executor;
}
}
My SQS consumer Service class is below.
#Service
public class RawConsumer {
#SqsListener(deletionPolicy = SqsMessageDeletionPolicy.NEVER, value = "${input.sqs.queuename}")
public void sqsListener(S3EventNotification event, Acknowledgment ack) throws Exception {
// Handle event here
}
I hope that helps, let me know if you have any issues.
What the question author did not mention is that he tried to customize the Jackson ObjectMapper. Therefore, he instantiated a MappingJackson2MessageConverter, wrapped that in a PayloadArgumentResolver and set this as the single HandlerMethodArgumentResolver on QueueMessageHandlerFactory.setArgumentResolvers(). Doing this overrides the list of default argument resolvers defined in QueueMessageHandler.initArgumentResolvers() (which is invoked when creating an instance of QueueMessageHandler inside the QueueMessageHandlerFactory).
When e.g. only a PayloadArgumentResolver is set as single argument resolver, the Acknowledgement argument cannot be bound anymore.
A better solution than overriding the list of argument resolvers for customizing the Jackson message converter thus is to set the list of message converters on the QueueMessageHandlerFactory:
#Bean
fun queueMessageHandlerFactory(objectMapper: ObjectMapper): QueueMessageHandlerFactory {
val factory = QueueMessageHandlerFactory()
val messageConverter = MappingJackson2MessageConverter()
messageConverter.objectMapper = objectMapper
factory.setMessageConverters(listOf(messageConverter)) // <-- this is the important line.
return factory
}
The registered MessageConverters are inside QueueMessageHandler.initArgumentResolvers() used as PayloadArgumentResolvers.
Thus, this is a less intrusive change.

Why can I use reflection to call private methods of an external class?

I can use reflection to access and call private methods of a class outside of my library. Is this a bug or desired behaviour? If it's desired, how can I make it impossible for external code to access private members/methods?
library left;
class Thing {
void _priv(String s) {
print(s);
}
}
library right;
void main() {
var t = new Thing();
var mirror = reflect(t);
mirror.type.declarations.values
.where( (d) => d.isPrivate && d is MethodMirror )
.forEach( (d) {
print(d.simpleName == #_priv); // prints false
mirror.getField(d.simpleName).reflectee("Hello World"); // prints Hello World
});
}
This privacy is not a security feature, is's only to communicate to users of your API that such a method is intended for internal usage only. Access using mirrors can't be prevented.
Disallowing it in mirrors wouldn't prevent access because the VM and dart2js just mangle or prefix private method names to prevent name collisions with public methods. These names can be predicted or found using brute force and then be called.
Calling private methods are mostly useful in writing the DSL(Domain Specific Language)s.

Static variable becomes zero

I have the following code:
public static int smsCount = 0 ;
public void startListener()
{
SendListener smsListener;
smsListener = new SendListener() {
public boolean sendMessage(Message message) {
++smsCount;
return true;
}
};
SMS.addSendListener(smsListener);
}
When I use a debugger I see that the value of smsCount is increasing. However, for some reason, it returns zero when I try to access it from outside the class. Is there anything wrong with this code ? sendMessage is called whenever an SMS is sent.
To expand on John B's comment, and to be more specific are you accessing it from a different runtime (application) context? Each runtime context has its own global (and therefore) static namespace. To ensure an object is a global singleton you should use the RuntimeStore.

Resources