Karaf executing commands in java console - osgi

The below code executes karaf commands in the console. This is working fine in karaf version 3.0.3. It fails in 4.0.0 or above
#Inject
CommandProcessor commandProcessor;
private class dummyCallable implements Callable{
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
final PrintStream printStream = new PrintStream(byteArrayOutputStream);
final CommandSession commandSession = commandProcessor.createSession(System.in, printStream, System.err);
String[] commands;
dummyCallable( String[] commands){
this.commands = commands;
}
public String call() {
try {
for(String command:commands) {
System.err.println(command);
commandSession.execute(command);
}
} catch (Exception e) {
e.printStackTrace(System.err);
}
return byteArrayOutputStream.toString();
}
}
protected String executeCommands(final String ...commands) {
String response;
dummyCallable dd = new dummyCallable(commands);
ExecutorService executor = Executors.newFixedThreadPool(1);
FutureTask<String> futureTask2 = new FutureTask<String>(dd);
try {
executor.submit(futureTask2);
response = futureTask2.get();
} catch (Exception e) {
e.printStackTrace(System.err);
response = "SHELL COMMAND TIMED OUT: ";
}
return response;
}
Can anybody provide me with a code which will work karaf 4.0.0

In Karaf 4, you should inject into your services a SessionFactory and call sessionFactory.createSession(System.in, printStream, System.err)
The methods are the same between Karaf3 and Karaf4, the class and package have changed :
CommandProcessor => SessionFactory
CommandSession => Session

Related

Loading value from json upon start up application

I want to load the values from json file upon the Spring Boot Application is started.
My code for the Configuration File is like the below:
#Configuration
#Getter
public class FedexAPIConfig {
private final static String JSON_FILE = "/static/config/fedex-api-credentials.json";
private final boolean IS_PRODUCTION = false;
private FedexAPICred apiCredentials;
public FedexAPIConfig() {
try (InputStream in = getClass().getResourceAsStream(JSON_FILE);
BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
JSONObject json = new JSONObject();
// this.apiCredentials = new JSONObject(new JSONTokener(reader));
if (IS_PRODUCTION) {
json = new JSONObject(new JSONTokener(reader)).getJSONObject("production");
} else {
json = new JSONObject(new JSONTokener(reader)).getJSONObject("test");
}
System.out.println(json.toString());
this.apiCredentials = FedexAPICred.builder()
.url(json.optString("url"))
.apiKey(json.optString("api_key"))
.secretKey(json.optString("secret_key"))
.build();
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
and with this, when the application is in progress of startup, values are successfully printed on the console.Startup console log
When I tried to call this value from other ordinary class, like the below:, it brings nothing but just throws NullPointerException... What are my faults and what shall I do?
public class FedexOAuthTokenManager extends OAuthToken {
private static final String VALIDATE_TOKEN_URL = "/oauth/token";
private static final String GRANT_TYPE_CLIENT = "client_credentials";
private static final String GRANT_TYPE_CSP = "csp_credentials";
#Autowired
private FedexAPIConfig fedexApiConfig;
#Autowired
private Token token;
#Override
public void validateToken() {
// This is the part where "fedexApiConfig" is null.
FedexAPICred fedexApiCred = fedexApiConfig.getApiCredentials();
Response response = null;
try {
RequestBody body = new FormBody.Builder()
.add("grant_type", GRANT_TYPE_CLIENT)
.add("client_id", fedexApiCred.getApiKey())
.add("client_secret", fedexApiCred.getSecretKey())
.build();
response = new HttpClient().post(fedexApiCred.getUrl() + VALIDATE_TOKEN_URL, body);
if (response.code() == 200) {
JSONObject json = new JSONObject(response.body().string());
token.setAccessToken(json.optString("access_token"));
token.setTokenType(json.optString("token_type"));
token.setExpiredIn(json.optInt("expires_in"));
token.setExpiredDateTime(LocalDateTime.now().plusSeconds(json.optInt("expires_in")));
token.setScope(json.optString("scope"));
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
fedexApiConfg is null even though I autowired it in prior to call.
And this FedexOAuthTokenManager is called from other #Component class by new FedexOAuthTokenManager()
Did you try like below?
Step 1: Create one Configuration class like below
public class DemoConfig implements ApplicationListener<ApplicationPreparedEvent> {
#Override
public void onApplicationEvent(ApplicationPreparedEvent event) {
//Load the values from the JSON file and populate the application
//properties dynamically
ConfigurableEnvironment environment = event.getApplicationContext().getEnvironment();
Properties props = new Properties();
props.put("spring.datasource.url", "<my value>");
//Add more properties
environment.getPropertySources().addFirst(new PropertiesPropertySource("myProps", props));
}
To listen to a context event, a bean should implement the ApplicationListener interface which has just one method onApplicationEvent().The ApplicationPreparedEvent is invoked very early in the lifecycle of the application
Step 2: Customize in src/main/resources/META-INF/spring.factories
org.springframework.context.ApplicationListener=com.example.demo.DemoConfig
Step 3: #Value in spring boot is commonly used to inject the configuration values into the spring boot application. Access the properties as per your wish.
#Value("${spring.datasource.url}")
private String valueFromJSon;
Try this sample first in your local machine and then modify your changes accordingly.
Refer - https://www.baeldung.com/spring-value-annotation
Refer - https://www.knowledgefactory.net/2021/02/aws-secret-manager-service-as.html

Send emails to multiple email addresses, It feeds email addresses from a csv file

I wanna create an application to send emails to several recipients. It feeds email addresses from a csv file and sends an email to each recipient, and I'm getting some trouble doing this.
Could you help me please?
Here is my CSVHelper.java
#Component
public class CSVHelper
{
public static String TYPE = "text/csv";
static String[] HEADERs = { "id", "email", "dateEcheance"};
//This method is used to filter the csv file and get only the emails
public List<ContactsFile> csvToEmails() throws NumberFormatException, ParseException
{
InputStream is = null;
try (BufferedReader fileReader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
CSVParser csvParser = new CSVParser(fileReader, CSVFormat.DEFAULT.withFirstRecordAsHeader().withIgnoreHeaderCase().withTrim());)
{
List<ContactsFile> emailsList = new ArrayList<>();
Iterable<CSVRecord> csvRecords = csvParser.getRecords();
for (CSVRecord csvRecord : csvRecords)
{
ContactsFile contact = new ContactsFile(csvRecord.get("email"));
emailsList.add(contact);
}
System.out.println(emailsList);
return emailsList;
}
catch (IOException e) { throw new RuntimeException("fail to get emails: " + e.getMessage()); }
}
We call csvToEmails() method in the controller to send the emails
#Autowired
private CSVHelper csvHelper;
#PostMapping("/getdetails")
public #ResponseBody EmailNotification sendMail(#RequestBody EmailNotification details) throws Exception {
MimeMessage message = sender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message,
MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED,
StandardCharsets.UTF_8.name());
try {
helper.setTo((InternetAddress) csvHelper.csvToEmails());
helper.setText(details.getMessage(),true);
helper.setSubject("Test Mail");
} catch (javax.mail.MessagingException e) {
e.printStackTrace();
}
sender.send(message);
return details;
this is an example of the csv file:
id,email,dateEcheance
1,address#email.com,10/05/2021
2,address2#email.com,10/02/2021
I'm new to spring boot, and I'm in trouble completing this project.
Assuming that you've mail server configurations in place. First, you need to provide the JavaMailSender implementation. Spring does provide the implementation for the same. You've to create a bean and config the mail server configurations as follows.
#Configuration
public class MailConfig {
#Autowired
private Environment env;
#Bean
public JavaMailSender mailSender() {
try {
JavaMailSenderImpl mailSenderImpl = new JavaMailSenderImpl();
mailSenderImpl.setHost(env.getRequiredProperty("mail.smtp.host"));
mailSenderImpl.setUsername(env.getRequiredProperty("mail.smtp.username"));
mailSenderImpl.setPassword(env.getRequiredProperty("mail.smtp.password"));
mailSenderImpl.setDefaultEncoding(env.getRequiredProperty("mail.smtp.encoding"));
mailSenderImpl.setPort(Integer.parseInt(env.getRequiredProperty("mail.smtp.port")));
mailSenderImpl.setProtocol(env.getRequiredProperty("mail.transport.protocol"));
Properties p = new Properties();
p.setProperty("mail.smtp.starttls.enable", "true");
p.setProperty("mail.smtp.auth", "true");
mailSenderImpl.setJavaMailProperties(p);
return mailSenderImpl;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Configuration settings in application.properties. Add settings according to the mail server.
# SMTP mail settings
mail.smtp.host=**********
mail.smtp.username=**********
mail.smtp.password=**********
mail.smtp.port=**********
mail.smtp.socketFactory.port=**********
mail.smtp.encoding=utf-8
mail.transport.protocol=smtp
mail.smtp.auth=true
mail.smtp.timeout=10000
mail.smtp.starttls.enable=true
mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
CSVHelper.java
#Component
public class CSVHelper {
// This method is used to filter the csv file and get only the emails
public List<String> csvToEmails() {
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("csvFile.csv");
try (BufferedReader fileReader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
CSVParser csvParser = new CSVParser(fileReader,
CSVFormat.DEFAULT.withFirstRecordAsHeader().withIgnoreHeaderCase().withTrim());) {
List<String> emails = new ArrayList<>();
Iterable<CSVRecord> csvRecords = csvParser.getRecords();
for (CSVRecord csvRecord : csvRecords) {
String email = csvRecord.get("email");
emails.add(email);
}
return emails;
} catch (IOException e) {
throw new RuntimeException("fail to get emails: " + e.getMessage());
}
}
}
Send mail service
#Service
public class MailSenderService {
#Autowired
private CSVHelper csvHelper;
#Autowired
private JavaMailSender sender;
public void sendMail(EmailNotification details) {
try {
List<String> recipients = csvHelper.csvToEmails();
String[] to = recipients.stream().toArray(String[]::new);
JavaMailSenderImpl jms = (JavaMailSenderImpl) sender;
MimeMessage message = jms.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
// add the sender email address below
helper.setFrom("sender#mail.com");
helper.setTo(to);
helper.setText(details.getMessage(), true);
helper.setSubject("Test Mail");
sender.send(message);
} catch (javax.mail.MessagingException | NumberFormatException e) {
// action for exception case
}
}
}

couldn't find method readString(Path) while loading BulkApi

I'm going to load the bulk of data using BulkApi but while compiling the code it shows me the error.
private static final Logger log = LoggerFactory.getLogger(BulkApiService.class);
#Autowired
public ElasticSearchConfig elasticSearchConfig;
private static String FOLDER_PATH = "src/main/resources/allFiles";
public void loadAllDataUsingBulkApi() {
Client client = elasticSearchConfig.client();
AtomicReference<BulkRequestBuilder> request = new AtomicReference<>(client.prepareBulk());
AtomicInteger counter = new AtomicInteger();
try (Stream<Path> filePathStream = Files.walk(Paths.get(FOLDER_PATH))) {
filePathStream.forEach(filePath -> {
if (Files.isRegularFile(filePath)) {
counter.getAndIncrement();
try {
String content = Files.readString(filePath);
JSONObject contentJson = new JSONObject(content);
HashMap contentMap = new Gson().fromJson(contentJson.toString(), HashMap.class);
request.get().add(client.prepareIndex("indexName", "default").setSource(contentMap));
} catch (IOException ignore) {
log.error(ignore.toString());
}
}
});
BulkResponse bulkResponse = request.get().execute().actionGet();
} catch (Exception e) {
log.error(e.toString());
}
}
}
Expected Output : it should load all the data on specified path to ES.
Actual output :
Error on "String content = Files.readString(filePath);" that couldn't find symbol.
symbol: method readString(Path)
location: class Files

How to fix this method renaming problem with Java 8 ASM

Recently I coded an Obfuscator with ASM in Java and wanted to rename classes, methods, and fields. But the problem is, that the code doesn't work it should too, and I have no clue how to fix that. The problem is, that if I obfuscate a jar every method in the class gets renamed, but sometimes (not every time) a bit of code is not getting renamed, so the jar can't be executed. E.g.
public abstract class ColorThread implements Runnable
{
#Getter
private final String name;
#Getter
private Thread thread;
public ColorThread(final String name) {
this.name = name;
Runtime.getRuntime().addShutdownHook(new Thread(this::close));
}
#Override
public void run() {
throw new NotOverriddenException("The Thread \"" + getName() + "\" is not overwritten.");
}
/**
* This method interrupts the running thread.
*/
public void close() {
this.getThread().interrupt();
}
public void start() { //<- Method gets renamed e.g "⢍⢖⣕⠟⡨⠣"
this.thread = new Thread(this, this.getName());
thread.start();
}
}
So this class got obfuscated but later in other code which calls:
final ConnectThread connectThread = new ConnectThread();
connectThread.start(); // <- this line
the line with connectThread.start(); isn't renamed to "connectThread.⢍⢖⣕⠟⡨⠣();". If I use another class which extends ColorThread e.g. ReceiveThread, the start method gets renamed in this bit of code.
I struggled every time with this problem if I made an Obfuscator and because of it I ended the project. But now I want to ask here if someone can help me. Sorry for this long post, but I wanted to give everything needed to see the problem.
The Project is running on Java 1.8.0_161 with ASM-All as a dependency.
To read a jar i use this method. It will store all classes in an ArrayList:
try (final JarFile jarFile = new JarFile(inputFile)) {
final Enumeration<JarEntry> jarEntryEnumeration = jarFile.entries();
while (jarEntryEnumeration.hasMoreElements()) {
final JarEntry jarEntry = jarEntryEnumeration.nextElement();
if (jarEntry.isDirectory())
continue;
final byte[] bytes = this.readInputStream(jarFile.getInputStream(jarEntry));
if (jarEntry.getName().endsWith(".class")) {
if (jarEntry.getName().endsWith("module-info.class"))
continue;
final ClassNode classNode = new ClassNode();
// new ClassReader(bytes).accept(classNode, ClassReader.EXPAND_FRAMES | ClassReader.SKIP_DEBUG);
new ClassReader(bytes).accept(classNode, ClassReader.EXPAND_FRAMES);
this.classes.add(classNode);
} else {
if (jarEntry.getName().contains("MANIFEST.MF"))
continue;
this.files.put(jarEntry.getName(), bytes);
}
}
this.manifest = jarFile.getManifest();
} catch (final Exception ex) {
ex.printStackTrace();
}
After this i use my transformation system to rename the methods:
#Override
public void transform(final ArrayList<ClassNode> classes, final HashMap<String, byte[]> files) {
final String mainClass = this.getJarResources().getManifest().getMainAttributes().getValue("Main-Class").replace(".", "/");
final HashMap<String, String> methodNames = new HashMap<>();
for (final ClassNode classNode : classes) {
for (final Object methodObj : classNode.methods) {
if (!(methodObj instanceof MethodNode))
continue;
final MethodNode methodNode = (MethodNode) methodObj;
if (methodNode.name.equals("<init>"))
continue;
if (methodNode.name.equals(mainClass) || methodNode.name.equals("main"))
continue;
methodNames.put(classNode.name + "." + methodNode.name + methodNode.desc, this.generateString(6));
}
}
this.remapClasses(classes, methodNames);
}
The remap method looks like this:
public void remapClasses(final ArrayList<ClassNode> classes, final HashMap<String, String> remappedNames) {
final SimpleRemapper simpleRemapper = new SimpleRemapper(remappedNames);
for (int index = 0; index < classes.size(); index++) {
final ClassNode realNode = classes.get(index);
final ClassNode copyNode = new ClassNode();
final ClassRemapper classRemapper = new ClassRemapper(copyNode, simpleRemapper);
realNode.accept(classRemapper);
classes.set(index, copyNode);
}
}
At the end i write the file:
public void writeFile() {
try (final JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream(this.outputFile), this.manifest)) {
for (final ClassNode classNode : this.classes) {
final ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classNode.accept(writer);
jarOutputStream.putNextEntry(new JarEntry(classNode.name + ".class"));
jarOutputStream.write(writer.toByteArray());
jarOutputStream.closeEntry();
}
for (final Map.Entry<String, byte[]> file : this.files.entrySet()) {
final String filePath = file.getKey();
if(filePath.endsWith(".kotlin_module") || filePath.contains("maven") || filePath.contains("3rd-party-licenses"))
continue;
jarOutputStream.putNextEntry(new JarEntry(filePath));
jarOutputStream.write(file.getValue());
jarOutputStream.closeEntry();
}
} catch (final Exception ex) {
ex.printStackTrace();
}
}

android async task executing api's repeteadly

I am using Android Async Task function to execute an api using urlconnection. this api in turn sends emails to selected users.Now the issue is I am getting spammed by these emails at first I thought of it as an server side issue or my script but I created a new api and used it on IOS version of my application and everything works fine.But when I execute it on android I start getting spams,so I think the Issue lies in my android programming.
public class submitparse extends AsyncTask<String ,String,String> {
String Url;
#Override
protected String doInBackground(String... params) {
URL phonelink;
HttpURLConnection urlConnection = null;
try {
phonelink = new URL(params[0]);
urlConnection = (HttpURLConnection) phonelink
.openConnection();
urlConnection.connect();
InputStream in = urlConnection.getInputStream();
InputStreamReader isw = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isw);
String line = "";
StringBuffer buffer = new StringBuffer();
while ((line = br.readLine()) != null) {
buffer.append(line);
}
String finalresult = buffer.toString();
return finalresult;
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
urlConnection.disconnect();
} catch (Exception e) {
e.printStackTrace(); //If you want further info on failure...
}
}
return null;
}
I am using this command to call it..
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String link = "";
new submitparse().execute(link);
}
});
On getting result I start another activity,where link is a string containing url.
If you don't care, you can also use just a new Thread. That should fit your needs and works fine. As far as I read, you don't need to use an AsyncTask and therefore IMO a normal Thread would be better.
// Runnable uiThreadRunnable = new Runnable.....
Handler handler = new Handler(); // import android.os.Handler
Runnable runnable = new Runnable() {
public void run() {
// do your stuff
// use 'handler.post(uiThreadRunnable);' to if you NEED to run something on main thread
}
};
Thread thread = new Thread(runnable);
thread.start();

Resources