Example for IFA_TTLLLBINARY - iso8583

Hey i'm a Jpos newbie and i'm having a problem with a field that's using the IFA_TTLLLBINARY
ISOMsg isoMsg = new ISOMsg();
isoMsg.setPackager(packager);
isoMsg1.setMTI("0100");
//...
isoMsg.set(55 ,"6F1A840E315041592E5359532E4444463031A5088801025F2D02656E");
//...
logISOMsg(isoMsg);
byte[] data = isoMsg.pack();
System.out.println("RESULT : " + new String(data));
but i always get this error :
Can anyone tell me the reason why this error is showing .

Take a look at https://github.com/jpos/jPOS/blob/master/jpos/src/test/java/org/jpos/iso/packager/TaggedFieldPackagerBaseTest.java
as a starting point.

Related

PLC4X:Exception during scraping of Job

I'm actually developing a project that read data from 19 PLCs Siemens S1500 and 1 modicon. I have used the scraper tool following this tutorial:
PLC4x scraper tutorial
but when the scraper is working for a little amount of time I get the following exception:
I have changed the scheduled time between 1 to 100 and I always get the same exception when the scraper reach the same number of received messages.
I have tested if using PlcDriverManager instead of PooledPlcDriverManager could be a solution but the same problem persists.
In my pom.xml I use the following dependency:
<dependency>
<groupId>org.apache.plc4x</groupId>
<artifactId>plc4j-scraper</artifactId>
<version>0.7.0</version>
</dependency>
I have tried to change the version to an older one like 0.6.0 or 0.5.0 but the problem still persists.
If I use the modicon (Modbus TCP) I also get this exception after a little amount of time.
Anyone knows why is happening this error? Thanks in advance.
Edit: With the scraper version 0.8.0-SNAPSHOT I continue having this problem.
Edit2: This is my code, I think the problem can be that in my scraper I am opening a lot of connections and when it reaches 65526 messages it fails. But since all the processing is happenning inside the lambda function and I'm using a PooledPlcDriverManager, I think the scraper is using only one connection so I dont know where is the mistake.
try {
// Create a new PooledPlcDriverManager
PlcDriverManager S7_plcDriverManager = new PooledPlcDriverManager();
// Trigger Collector
TriggerCollector S7_triggerCollector = new TriggerCollectorImpl(S7_plcDriverManager);
// Messages counter
AtomicInteger messagesCounter = new AtomicInteger();
// Configure the scraper, by binding a Scraper Configuration, a ResultHandler and a TriggerCollector together
TriggeredScraperImpl S7_scraper = new TriggeredScraperImpl(S7_scraperConfig, (jobName, sourceName, results) -> {
LinkedList<Object> S7_results = new LinkedList<>();
messagesCounter.getAndIncrement();
S7_results.add(jobName);
S7_results.add(sourceName);
S7_results.add(results);
logger.info("Array: " + String.valueOf(S7_results));
logger.info("MESSAGE number: " + messagesCounter);
// Producer topics routing
String topic = "s7" + S7_results.get(1).toString().substring(S7_results.get(1).toString().indexOf("S7_SourcePLC") + 9 , S7_results.get(1).toString().length());
String key = parseKey_S7("s7");
String value = parseValue_S7(S7_results.getLast().toString(),S7_results.get(1).toString());
logger.info("------- PARSED VALUE -------------------------------- " + value);
// Create my own Kafka Producer
ProducerRecord<String, String> record = new ProducerRecord<String, String>(topic, key, value);
// Send Data to Kafka - asynchronous
producer.send(record, new Callback() {
public void onCompletion(RecordMetadata recordMetadata, Exception e) {
// executes every time a record is successfully sent or an exception is thrown
if (e == null) {
// the record was successfully sent
logger.info("Received new metadata. \n" +
"Topic:" + recordMetadata.topic() + "\n" +
"Partition: " + recordMetadata.partition() + "\n" +
"Offset: " + recordMetadata.offset() + "\n" +
"Timestamp: " + recordMetadata.timestamp());
} else {
logger.error("Error while producing", e);
}
}
});
}, S7_triggerCollector);
S7_scraper.start();
S7_triggerCollector.start();
} catch (ScraperException e) {
logger.error("Error starting the scraper (S7_scrapper)", e);
}
So in the end indeed it was the PLC that was simply hanging up the connection randomly. However the NiFi integration should have handled this situation more gracefully. I implemented a fix for this particular error ... could you please give version 0.8.0-SNAPSHOT a try (or use 0.8.0 if we happen to have released it already)

Plc4x addressing system

I am discovering the Plc4x java implementation which seems to be of great interest in our field. But the youth of the project and the documentation makes us hesitate. I have been able to implement the basic hello world for reading out of our PLCs, but I was unable to write. I could not find how the addresses are handled and what the maskwrite, andMask and orMask fields mean.
Please can somebody explain to me the following example and detail how the addresses should be used?
#Test
void testWriteToPlc() {
// Establish a connection to the plc using the url provided as first argument
try( PlcConnection plcConnection = new PlcDriverManager().getConnection( "modbus:tcp://1.1.2.1" ) ){
// Create a new read request:
// - Give the single item requested the alias name "value"
var builder = plcConnection.writeRequestBuilder();
builder.addItem( "value-" + 1, "maskwrite:1[1]/2/3", 2 );
var writeRequest = builder.build();
LOGGER.info( "Synchronous request ..." );
var syncResponse = writeRequest.execute().get();
}catch(Exception e){
e.printStackTrace();
}
}
I have used PLC4x for writing using the modbus driver with success. Here is some sample code I am using:
public static void writePlc4x(ProtocolConnection connection, String registerName, byte[] writeRegister, int offset)
throws InterruptedException {
// modbus write works ok writing one record per request/item
int size = 1;
PlcWriteRequest.Builder writeBuilder = connection.writeRequestBuilder();
if (writeRegister.length == 2) {
writeBuilder.addItem(registerName, "register:" + offset + "[" + size + "]", writeRegister);
}
...
PlcWriteRequest request = writeBuilder.build();
request.execute().whenComplete((writeResponse, error) -> {
assertNotNull(writeResponse);
});
Thread.sleep((long) (sleepWait4Write * writeRegister.length * 1000));
}
In the case of modbus writing there is an issue regarding the return of the writer Future, but the write is done. In the modbus use case I don't need any mask stuff.

Plc4x cannot read more than 9 registers at once

I am trying to understand the address system in the plac4x java implementation. Below an example of the reading code of the plcs:
#Test
void testReadingFromPlc() {
// Establish a connection to the plc using the url provided as first argument
try( PlcConnection plcConnection = new PlcDriverManager().getConnection( "modbus:tcp://1.1.2.1" ) ){
// Create a new read request:
// - Give the single item requested the alias name "value"
var builder = plcConnection.readRequestBuilder();
builder.addItem( "value-" + 1, "register:1[9]" );
builder.addItem( "value-" + 2, "coil:1000[8]" );
var readRequest = builder.build();
LOGGER.info( "Synchronous request ..." );
var syncResponse = readRequest.execute().get();
// Simply iterating over the field names returned in the response.
var bytes = syncResponse.getAllByteArrays( "value-1" );
bytes.forEach( item -> System.out.println( TopicsMapping.byteArray2IntegerArray( item )[0] ) );
var booleans = syncResponse.getAllBooleans( "value-2" );
booleans.forEach( System.out::println );
}catch(Exception e){
e.printStackTrace();
}
}
Our PLCs manage 16 registers, but the regex of the addresses don't allow to have a quantity bigger than 9. Is it possible to change this?
Moreover, if I try to add an other field with the same purpose then no reading happen:
var builder = plcConnection.readRequestBuilder();
builder.addItem( "value-" + 0, "register:26[8]" );
builder.addItem( "value-" + 1, "register:34[8]" );
builder.addItem( "value-" + 2, "coil:1000[8]" );
var readRequest = builder.build();
Any help much appreciated. Could you also show me where I can find more information on this framework?
I am reading and writing using the modbus driver in PLC4x with success. I have attached some writing code to your other question at: Plc4x addressing system
About reading, here is some code:
public static PlcReadResponse readModbusTestData(ProtocolClient client,
String registerName,
int offset,
int size,
String registerType)
throws ExecutionException, InterruptedException, TimeoutException {
PlcReadRequest readRequest = client.getConnection().readRequestBuilder()
.addItem(registerName, registerType + ":" + offset + "[" + size + "]").build();
return readRequest.execute().get(2, TimeUnit.SECONDS);
}
The multiple read adding more items to the PlcReadRequest has not been tested yet by me, but it should work. Writing several items is working.
In any case, in order to understand how PLC4x works for modbus or opc-ua I have needed to dive into the source code. It works, but you need to read the source code for the details at its current state.

GOOGLE DOCS API Invalid requests[0].updateTextStyle: Index 4 must be less than the end index of the referenced segment, 2.",

I've created a document using Google Docs API, but when I try to modify its options or add text, it gives me this error:
http://prntscr.com/naf0nm
The thing is if I open the document and click enter many times ( to make many lines) then execution and modification works. Can anyone help me?? What do I need to do to not get this error?
String text1 = "hola, llegó papa";
List<Request> requests = new ArrayList<>();
requests.add(new Request().setInsertText(new InsertTextRequest()
.setText(text1)
.setLocation(new Location().setIndex(25))));
BatchUpdateDocumentRequest body = new BatchUpdateDocumentRequest().setRequests(requests);
BatchUpdateDocumentResponse response = service.documents()
.batchUpdate(idDoc, body).execute();
Here the method to create doc:
private static void createDoc(Docs service) throws IOException {
Document doc = new Document()
.setTitle("TEXTO CAMBIADO");
doc = service.documents().create(doc)
.execute();
System.out.println("Created document with title: " + doc.getTitle());
idDoc = doc.getDocumentId();
}
It is very late for answer but it can help to others.
May be this answer can help you. someone has answered here
Also you have to write backword to get the last inserted text at the starting of doc.
I just found another way to write text at end of doc. You don't need to set the location, just do this way..
public void insertText(Docs docsService) throws IOException {
List<Request> requests = new ArrayList<>();
requests.add(new Request().setInsertText(new InsertTextRequest()
.setText("Name : {{NAME}}\n")
.setEndOfSegmentLocation(new EndOfSegmentLocation())));
requests.add(new Request().setInsertText(new InsertTextRequest()
.setText("\nDOB: {{DOB}}\n")
.setEndOfSegmentLocation(new EndOfSegmentLocation())));
requests.add(new Request().setInsertText(new InsertTextRequest()
.setText("\nMobile: {{MOBILE}}\n")
.setEndOfSegmentLocation(new EndOfSegmentLocation())));
BatchUpdateDocumentRequest body = new BatchUpdateDocumentRequest().setRequests(requests);
BatchUpdateDocumentResponse response = docsService.documents()
.batchUpdate(Constants.DOCUMENT_ID, body).execute();
}

Paypal Php Sdk - NotifyUrl is not a fully qualified URL Error

I have this code
$product_info = array();
if(isset($cms['site']['url_data']['product_id'])){
$product_info = $cms['class']['product']->get($cms['site']['url_data']['product_id']);
}
if(!isset($product_info['id'])){
/*
echo 'No product info.';
exit();
*/
header_url(SITE_URL.'?subpage=user_subscription#xl_xr_page_my%20account');
}
$fee = $product_info['yearly_price_end'] / 100 * $product_info['fee'];
$yearly_price_end = $product_info['yearly_price_end'] + $fee;
$fee = ($product_info['setup_price_end'] / 100) * $product_info['fee'];
$setup_price_end = $product_info['setup_price_end'] + $fee;
if(isset($_SESSION['discountcode_amount'])){
$setup_price_end = $setup_price_end - $_SESSION['discountcode_amount'];
unset($_SESSION['discountcode_amount']);
}
$error = false;
$plan_id = '';
$approvalUrl = '';
$ReturnUrl = SITE_URL.'payment/?payment_type=paypal&payment_page=process_agreement';
$CancelUrl = SITE_URL.'payment/?payment_type=paypal&payment_page=cancel_agreement';
$now = $cms['date'];
$now->modify('+5 minutes');
$apiContext = new \PayPal\Rest\ApiContext(
new \PayPal\Auth\OAuthTokenCredential(
$cms['options']['plugin_paypal_clientid'], // ClientID
$cms['options']['plugin_paypal_clientsecret'] // ClientSecret
)
);
use PayPal\Api\ChargeModel;
use PayPal\Api\Currency;
use PayPal\Api\MerchantPreferences;
use PayPal\Api\PaymentDefinition;
use PayPal\Api\Plan;
use PayPal\Api\Patch;
use PayPal\Api\PatchRequest;
use PayPal\Common\PayPalModel;
use PayPal\Api\Agreement;
use PayPal\Api\Payer;
use PayPal\Api\ShippingAddress;
// Create a new instance of Plan object
$plan = new Plan();
// # Basic Information
// Fill up the basic information that is required for the plan
$plan->setName($product_info['name'])
->setDescription($product_info['desc_text'])
->setType('fixed');
// # Payment definitions for this billing plan.
$paymentDefinition = new PaymentDefinition();
// The possible values for such setters are mentioned in the setter method documentation.
// Just open the class file. e.g. lib/PayPal/Api/PaymentDefinition.php and look for setFrequency method.
// You should be able to see the acceptable values in the comments.
$setFrequency = 'Year';
//$setFrequency = 'Day';
$paymentDefinition->setName('Regular Payments')
->setType('REGULAR')
->setFrequency($setFrequency)
->setFrequencyInterval("1")
->setCycles("999")
->setAmount(new Currency(array('value' => $yearly_price_end, 'currency' => $cms['session']['client']['currency']['iso_code'])));
// Charge Models
$chargeModel = new ChargeModel();
$chargeModel->setType('SHIPPING')
->setAmount(new Currency(array('value' => 0, 'currency' => $cms['session']['client']['currency']['iso_code'])));
$paymentDefinition->setChargeModels(array($chargeModel));
$merchantPreferences = new MerchantPreferences();
// ReturnURL and CancelURL are not required and used when creating billing agreement with payment_method as "credit_card".
// However, it is generally a good idea to set these values, in case you plan to create billing agreements which accepts "paypal" as payment_method.
// This will keep your plan compatible with both the possible scenarios on how it is being used in agreement.
$merchantPreferences->setReturnUrl($ReturnUrl)
->setCancelUrl($CancelUrl)
->setAutoBillAmount("yes")
->setInitialFailAmountAction("CONTINUE")
->setMaxFailAttempts("0")
->setSetupFee(new Currency(array('value' => $setup_price_end, 'currency' => $cms['session']['client']['currency']['iso_code'])));
$plan->setPaymentDefinitions(array($paymentDefinition));
$plan->setMerchantPreferences($merchantPreferences);
// ### Create Plan
try {
$output = $plan->create($apiContext);
} catch (Exception $ex){
die($ex);
}
echo $output->getId().'<br />';
echo $output.'<br />';
Been working with paypal php sdk for some days now and my code stop working.
So i went back to basic and i am still getting the same damn error.
I am trying to create a plan for subscription but getting the following error:
"NotifyUrl is not a fully qualified URL"
I have no idea how to fix this as i dont use NotfifyUrl in my code?
Could be really nice if anyone had an idea how to fix this problem :)
Thanks
PayPal did a update to their API last night which has caused problem within their SDK.
They are sending back null values in their responses.
I MUST stress the error is not on sending the request to PayPal, but on processing their response.
BUG Report : https://github.com/paypal/PayPal-PHP-SDK/issues/1151
Pull Request : https://github.com/paypal/PayPal-PHP-SDK/pull/1152
Hope this helps, but their current SDK is throwing exceptions.
Use below simple fix.
Replace below function in vendor\paypal\rest-api-sdk-php\lib\PayPal\Api\MerchantPreferences.php
public function setNotifyUrl($notify_url)
{
if(!empty($notify_url)){
UrlValidator::validate($notify_url, "NotifyUrl");
}
$this->notify_url = $notify_url;
return $this;
}
If you get the same error for return_url/cancel_url, add the if condition as above.
Note: This is not a permanent solution, you can use this until getting the update from PayPal.
From the GitHub repo for the PayPal PHP SDK, I see that the error you mentioned is thrown when MerchantPreferences is not given a valid NotifyUrl. I see you're setting the CancelUrl and ReturnUrl, but not the NotifyUrl. You may simply need to set that as well, i.e.:
$NotifyUrl = (some url goes here)
$obj->setNotifyUrl($NotifyUrl);
Reason behind it!
error comes from.
vendor\paypal\rest-api-sdk-php\lib\PayPal\Validation\UrlValidator.php
line.
if (filter_var($url, FILTER_VALIDATE_URL) === false) {
throw new \InvalidArgumentException("$urlName is not a fully qualified URL");
}
FILTER_VALIDATE_URL: according to this php function.
INVALID URL: "http://cat_n.domain.net.in/"; // IT CONTAIN _ UNDERSCORE.
VALID URL: "http://cat-n.domain.net.in/"; it separated with - dash
here you can dump your url.
vendor\paypal\rest-api-sdk-php\lib\PayPal\Validation\UrlValidator.php
public static function validate($url, $urlName = null)
{
var_dump($url);
}
And then check this here: https://www.w3schools.com/PHP/phptryit.asp?filename=tryphp_func_validate_url
you can check here what character will reason for invalid.