How to write a generic remote ejb lookup? - java

I have the following util class for looking up Remote EJB. It's currently duplicated in many places. How can I write it once and reuse and only pass the interface name to tell it which EJB I'm looking for.
I have limited knowledge of Java Generics.
#ApplicationScoped
public class ServiceLookupUtil {
public static final String JBOSS_EJB_CLIENT = "org.jboss.ejb.client.naming";
public static final String JBOSS_NAMING_CONTEXT = "jboss.naming.client.ejb.context";
private AddressService addressService;
private Context context;
private Logger log;
public ServiceLookupUtil() {
super();
}
#Inject
public ServiceLookupUtil(Logger log) {
this.log = log;
}
public AddressService lookupAddressService() {
if (addressService == null) {
try {
context = getInitialContext();
log.debug("Looking up: " + getLookupName());
addressService = (AddressService) context.lookup(getLookupName());
return addressService;
} catch (Exception ex) {
log.error("Could not get reference to AddressService ", ex);
} finally {
if (context != null) {
try {
context.close();
} catch (NamingException e) {
log.error(e.getMessage(), e);
}
}
}
}
return addressService;
}
public Context getInitialContext() {
try {
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.URL_PKG_PREFIXES, JBOSS_EJB_CLIENT);
jndiProperties.put(JBOSS_NAMING_CONTEXT, true);
return new InitialContext(jndiProperties);
} catch (NamingException e) {
log.error(e.getMessage(), e);
}
return context;
}
private String getLookupName() {
return "ejb:" + AddressService.APP_NAME + "/" + AddressService.MODULE_NAME + "/" + AddressService.BEAN_NAME + "!" + AddressService.class.getName();
}
}

Here is the answer (change APP_NAME, MODULE_NAME and BEAN_NAME_CONVETION_ADD):
#ApplicationScoped
public class ServiceLookupUtil {
public static final String JBOSS_EJB_CLIENT = "org.jboss.ejb.client.naming";
public static final String JBOSS_NAMING_CONTEXT = "jboss.naming.client.ejb.context";
private Map<String, Object> services = new HashMap<String, Object>();
private Context context;
#Inject
private Logger log;
private static final String APP_NAME = "";
private static final String MODULE_NAME = "module-ejb";
private static final String BEAN_NAME_CONVETION_ADD = "Impl";
public ServiceLookupUtil() {
super();
}
#SuppressWarnings("unchecked")
public <S> S lookupService(Class<S> clazz) {
if (services.get(clazz.getName()) == null) {
S service = null;
try {
context = getInitialContext();
String jndi = getLookupName(clazz);
log.debug("Looking up: " + jndi);
service = (S) context.lookup(jndi);
services.put(clazz.getName(), service);
return service;
} catch (Exception ex) {
log.error("Could not get reference to AddressService ", ex);
} finally {
if (context != null) {
try {
context.close();
} catch (NamingException e) {
log.error(e.getMessage(), e);
}
}
}
}
return (S)services.get(clazz.getName());
}
private Context getInitialContext() {
try {
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.URL_PKG_PREFIXES, JBOSS_EJB_CLIENT);
jndiProperties.put(JBOSS_NAMING_CONTEXT, true);
return new InitialContext(jndiProperties);
} catch (NamingException e) {
log.error(e.getMessage(), e);
}
return context;
}
private <S> String getLookupName(Class<S> clazz) {
return "ejb:" + APP_NAME + "/" + MODULE_NAME + "/" + clazz.getSimpleName() + BEAN_NAME_CONVETION_ADD + "!" + clazz.getName();
}
}

Related

Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized

I'm trying to launch my application, the meaning of which is to place an ad on the google cloud platform
Here is my code
import com.google.api.services.jobs.v3.CloudTalentSolution;
import com.google.api.services.jobs.v3.model.*;
import java.io.IOException;
import java.util.Arrays;
import java.util.Random;
public class BasicJobSample {
private static final String DEFAULT_PROJECT_ID = "projects/" + System.getenv("GOOGLE_CLOUD_PROJECT");
private static CloudTalentSolution talentSolutionClient = JobServiceQuickstart.getTalentSolutionClient();
public static Job generateJobWithRequiredFields(String companyName) {
String requisitionId = "jobWithRequiredFields:" + String.valueOf(new Random().nextLong());
ApplicationInfo applicationInfo = new ApplicationInfo().setUris(Arrays.asList("http://careers.google.com"));
Job job = new Job().setRequisitionId(requisitionId).setTitle("Software Engineer")
.setCompanyName(companyName).setApplicationInfo(applicationInfo)
.setDescription("Design, develop, test, deploy, maintain and improve software.");
System.out.println("Job generated: " + job);
return job;
}
public static Job createJob(Job jobToBeCreated) throws IOException {
try {
CreateJobRequest createJobRequest = new CreateJobRequest().setJob(jobToBeCreated);
Job jobCreated = talentSolutionClient.projects().jobs().create(DEFAULT_PROJECT_ID, createJobRequest)
.execute();
System.out.println("Job created: " + jobCreated);
return jobCreated;
} catch (IOException e) {
System.out.println("Got exception while creating job");
throw e;
}
}
public static Job getJob(String jobName) throws IOException {
try {
Job jobExisted = talentSolutionClient.projects().jobs().get(jobName).execute();
System.out.println("Job existed: " + jobExisted);
return jobExisted;
} catch (IOException e) {
System.out.println("Got exception while getting job");
throw e;
}
}
public static Job updateJob(String jobName, Job jobToBeUpdated) throws IOException {
try {
UpdateJobRequest updateJobRequest = new UpdateJobRequest().setJob(jobToBeUpdated);
Job jobUpdated = talentSolutionClient.projects().jobs().patch(jobName, updateJobRequest).execute();
System.out.println("Job updated: " + jobUpdated);
return jobUpdated;
} catch (IOException e) {
System.out.println("Got exception while updating job");
throw e;
}
}
public static Job updateJobWithFieldMask(String jobName, String fieldMask, Job jobToBeUpdated)
throws IOException {
try {
UpdateJobRequest updateJobRequest = new UpdateJobRequest().setUpdateMask(fieldMask)
.setJob(jobToBeUpdated);
Job jobUpdated = talentSolutionClient.projects().jobs().patch(jobName, updateJobRequest).execute();
System.out.println("Job updated: " + jobUpdated);
return jobUpdated;
} catch (IOException e) {
System.out.println("Got exception while updating job");
throw e;
}
}
public static void deleteJob(String jobName) throws IOException {
try {
talentSolutionClient.projects().jobs().delete(jobName).execute();
System.out.println("Job deleted");
} catch (IOException e) {
System.out.println("Got exception while deleting job");
throw e;
}
}
public static void main(String... args) throws Exception {
Company companyToBeCreated = BasicCompanySample.generateCompany();
Company companyCreated = BasicCompanySample.createCompany(companyToBeCreated);
String companyName = companyCreated.getName();
Job jobToBeCreated = generateJobWithRequiredFields(companyName);
Job jobCreated = createJob(jobToBeCreated);
String jobName = jobCreated.getName();
getJob(jobName);
Job jobToBeUpdated = jobCreated.setDescription("changedDescription");
updateJob(jobName, jobToBeUpdated);
updateJobWithFieldMask(jobName, "title", new Job().setTitle("changedJobTitle"));
deleteJob(jobName);
BasicCompanySample.deleteCompany(companyName);
try {
ListCompaniesResponse listCompaniesResponse = talentSolutionClient.projects().companies()
.list(DEFAULT_PROJECT_ID).execute();
System.out.println("Request Id is " + listCompaniesResponse.getMetadata().getRequestId());
if (listCompaniesResponse.getCompanies() != null) {
for (Company company : listCompaniesResponse.getCompanies()) {
System.out.println(company.getName());
}
}
} catch (IOException e) {
System.out.println("Got exception while listing companies");
throw e;
}
}
}
import com.google.api.services.jobs.v3.CloudTalentSolution;
import com.google.api.services.jobs.v3.model.Company;
import com.google.api.services.jobs.v3.model.CreateCompanyRequest;
import com.google.api.services.jobs.v3.model.UpdateCompanyRequest;
import java.io.IOException;
import java.util.Random;
public class BasicCompanySample {
private static final String DEFAULT_PROJECT_ID = "projects/" + System.getenv("GOOGLE_CLOUD_PROJECT");
private static CloudTalentSolution talentSolutionClient = JobServiceQuickstart.getTalentSolutionClient();
public static Company generateCompany() {
String companyName = "company:" + String.valueOf(new Random().nextLong());
Company company = new Company().setDisplayName("Google")
.setHeadquartersAddress("1600 Amphitheatre Parkway Mountain View, CA 94043")
.setExternalId(companyName);
System.out.println("Company generated: " + company);
return company;
}
public static Company createCompany(Company companyToBeCreated) throws IOException {
try {
CreateCompanyRequest createCompanyRequest = new CreateCompanyRequest().setCompany(companyToBeCreated);
Company companyCreated = talentSolutionClient.projects().companies()
.create(DEFAULT_PROJECT_ID, createCompanyRequest).execute();
System.out.println("Company created: " + companyCreated);
return companyCreated;
} catch (IOException e) {
System.out.println("Got exception while creating company");
throw e;
}
}
public static Company getCompany(String companyName) throws IOException {
try {
Company companyExisted = talentSolutionClient.projects().companies().get(companyName).execute();
System.out.println("Company existed: " + companyExisted);
return companyExisted;
} catch (IOException e) {
System.out.println("Got exception while getting company");
throw e;
}
}
public static Company updateCompany(String companyName, Company companyToBeUpdated) throws IOException {
try {
UpdateCompanyRequest updateCompanyRequest = new UpdateCompanyRequest().setCompany(companyToBeUpdated);
Company companyUpdated = talentSolutionClient.projects().companies()
.patch(companyName, updateCompanyRequest).execute();
System.out.println("Company updated: " + companyUpdated);
return companyUpdated;
} catch (IOException e) {
System.out.println("Got exception while updating company");
throw e;
}
}
public static Company updateCompanyWithFieldMask(String companyName, String fieldMask,
Company companyToBeUpdated) throws IOException {
try {
// String foo = String.format("?updateCompanyFields=%s",fieldMask);
UpdateCompanyRequest updateCompanyRequest = new UpdateCompanyRequest().setUpdateMask(fieldMask)
.setCompany(companyToBeUpdated);
Company companyUpdated = talentSolutionClient.projects().companies()
.patch(companyName, updateCompanyRequest).execute();
System.out.println("Company updated: " + companyUpdated);
return companyUpdated;
} catch (IOException e) {
System.out.println("Got exception while updating company");
throw e;
}
}
public static void deleteCompany(String companyName) throws IOException {
try {
talentSolutionClient.projects().companies().delete(companyName).execute();
System.out.println("Company deleted");
} catch (IOException e) {
System.out.println("Got exception while deleting company");
throw e;
}
}
}
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.jobs.v3.CloudTalentSolution;
import com.google.api.services.jobs.v3.model.Company;
import com.google.api.services.jobs.v3.model.ListCompaniesResponse;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.util.Collections;
public class JobServiceQuickstart {
private static final JsonFactory JSON_FACTORY = new JacksonFactory();
private static final NetHttpTransport NET_HTTP_TRANSPORT = new NetHttpTransport();
private static final String SCOPES = "https://www.googleapis.com/auth/jobs";
private static final String DEFAULT_PROJECT_ID = "projects/" + System.getenv("GOOGLE_CLOUD_PROJECT");
private static final CloudTalentSolution talentSolutionClient = createTalentSolutionClient(generateCredential());
private static CloudTalentSolution createTalentSolutionClient(GoogleCredentials credential) {
String url = "https://jobs.googleapis.com";
HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credential);
return new CloudTalentSolution.Builder(NET_HTTP_TRANSPORT, JSON_FACTORY, setHttpTimeout(requestInitializer))
.setApplicationName("JobServiceClientSamples").setRootUrl(url).build();
}
private static GoogleCredentials generateCredential() {
try {
// Credentials could be downloaded after creating service account
// set the `GOOGLE_APPLICATION_CREDENTIALS` environment variable, for example:
// export GOOGLE_APPLICATION_CREDENTIALS=/path/to/your/key.json
return GoogleCredentials.getApplicationDefault().createScoped(Collections.singleton(SCOPES));
} catch (Exception e) {
System.out.print("Error in generating credential");
throw new RuntimeException(e);
}
}
private static HttpRequestInitializer setHttpTimeout(final HttpRequestInitializer requestInitializer) {
return request -> {
requestInitializer.initialize(request);
request.setHeaders(new HttpHeaders().set("X-GFE-SSL", "yes"));
request.setConnectTimeout(1 * 60000); // 1 minute connect timeout
request.setReadTimeout(1 * 60000); // 1 minute read timeout
};
}
public static CloudTalentSolution getTalentSolutionClient() {
return talentSolutionClient;
}
I can’t figure out the authorization and I can’t figure out where I should write (in my application) all the authorization parameters
Here is the error I'm getting right now
Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
POST https://jobs.googleapis.com/v3/projects/null/companies
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:146)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:118)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:37)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:428)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1111)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:514)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:455)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:565)
at io.fortylines.tapintech.jobapi.BasicCompanySample.createCompany(BasicCompanySample.java:37)
at io.fortylines.tapintech.jobapi.BasicJobSample.main(BasicJobSample.java:116)
And one more note. When I debug I see that in this line
private static final String DEFAULT_PROJECT_ID = "projects/" + System.getenv("GOOGLE_CLOUD_PROJECT");
"projects/" = null
While in google cloud i created a project
Here are my application.properties
# application
server.port=8081
# database
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=
spring.cloud.gcp.core.enabled=true
spring.cloud.gcp.project-id=tab-in-tech
spring.cloud.gcp.credentials.location=file:/usr/local/key.json
spring.cloud.gcp.credentials.scopes=https://www.googleapis.com/auth/pubsub,https://www.googleapis.com/auth/sqlservice.admin
spring.cloud.gcp.config.name=
spring.cloud.gcp.config.credentials.encoded-key=
Maybe I'm doing something wrong here

Initialize class with static method not managed by Spring

I have a class called ConfigManagement which uses only static methods/fields. One of the static methods, called initializeConfig() takes a Property object (points at application.properties) as input and populates the fields and calls some other methods with the values from the application.properties file.
public class ConfigManagement {
private static String signatureAlgorithm;
private static String myName;
private static RSAPublicKey myPublicKey;
private static RSAPrivateKey myPrivateKey;
private static HashMap<String, RSAPublicKey> peerPubKeys = new HashMap<String, RSAPublicKey>();
private static boolean isInitialized = false;
/**
* #return the signatureAlgorithm
*/
public static void initializeConfig(Properties props) {
signatureAlgorithm = props.getProperty("cybertrust.crypto.signatureAlgorithm");
myName = props.getProperty("cybertrust.crypto.myName");
try {
try {
myPublicKey = Loader.getPublicKeyFromCertificateFile(props.getProperty("cybertrust.crypto.myCertificate"));
}
catch (Exception e) {
throw new IllegalStateException("cybertrust.crypto.myCertificate is empty, the file is not found or it contains invalid data");
}
try {
myPrivateKey = Loader.getPrivateKeyFromFile(props.getProperty("cybertrust.crypto.myPrivateKey"));
}
catch (Exception e) {
throw new IllegalStateException("cybertrust.crypto.myPrivateKey is empty, the file is not found or it contains invalid data");
}
peerPubKeys.put(myName, myPublicKey);
int peerCounter = 0;
do {
String peerNameProp = String.format("cybertrust.crypto.peerModules.%d.name", peerCounter);
String peerName = props.getProperty(peerNameProp);
if (peerName == null)
break;
String peerNameCertFileProp = String.format("cybertrust.crypto.peerModules.%d.certificate", peerCounter);
String peerNameCertFile = props.getProperty(peerNameCertFileProp);
if (peerNameCertFile == null) // Do not halt the program, produce though an error
Logger.getLogger("ConfigManagement").log(Level.SEVERE,
String.format("Property %s not found while property %s is defined", peerNameCertFile, peerNameProp));
// instantiate public key from file
try {
RSAPublicKey peerRsaPubKey = Loader.getPublicKeyFromCertificateFile(peerNameCertFile);
peerPubKeys.put(peerName, peerRsaPubKey);
}
catch (Exception e) {
Logger.getLogger("ConfigManagement").log(Level.SEVERE,
String.format("File %s specified in property %s not found or does not contains a valid RSA key", peerNameCertFile, peerNameCertFileProp)); }
peerCounter++;
} while (true);
}
catch (Exception e) {
throw(e);
}
if ((myPublicKey == null) || (signatureAlgorithm == null) || (myName == null))
throw new IllegalStateException("one of the properties cybertrust.crypto.signatureAlgorithm, cybertrust.crypto.myName, cybertrust.crypto.myPublicKey, cybertrust.crypto.myPrivateKey is not defined");
isInitialized = true;
}
private static void testInitialized() {
if (!isInitialized)
throw new IllegalStateException("The configuration has not been initialized");
}
public static String getSignatureAlgorithm() {
testInitialized();
return signatureAlgorithm;
}
/**
* #return the myName
*/
public static String getMyName() {
testInitialized();
return myName;
}
/**
* #return the myPublicKey
*/
public static RSAPublicKey getMyPublicKey() {
testInitialized();
return myPublicKey;
}
/**
* #return the myPrivateKey
*/
public static RSAPrivateKey getMyPrivateKey() {
testInitialized();
return myPrivateKey;
}
public static RSAPublicKey getPublicKey(String peerName) throws NoSuchElementException {
testInitialized();
RSAPublicKey result = peerPubKeys.get(peerName);
if (result == null)
throw new NoSuchElementException("No known key for module " + peerName);
else
return result;
}
}
The application.properties file looks something like this:
cybertrust.crypto.myName=tms1235.cybertrust.eu
cybertrust.crypto.myCertificate=tms1235.cert.pem
cybertrust.crypto.myPrivateKey=tms1235.key.pem
cybertrust.crypto.signatureAlgorithm=SHA256withRSA
cybertrust.crypto.peerModules.0.name=sga1234.cybertrust.eu
cybertrust.crypto.peerModules.0.certificate=sga1234.cert.pem
cybertrust.crypto.peerModules.1.name=tms1234.cybertrust.eu
cybertrust.crypto.peerModules.1.certificate=tms1234.cert.pem
In a simple Java project I run ConfigManagement.initializeConfig(props); in main() and the fields are initialized and I can use the rest of the methods. In Spring it's not that simple.
I am trying to integrate this code in a SpringBoot application and I don't know how/where to initialize this class.
I am posting the Spring configuration for reference:
#Configuration
#EnableWebMvc
#EnableTransactionManagement
#ComponentScan("com.cybertrust.tms")
//#PropertySource({ "classpath:persistence-mysql.properties" })
#PropertySource({ "classpath:model.properties" })
public class DemoAppConfig implements WebMvcConfigurer {
#Autowired
private Environment env;
private Logger logger = Logger.getLogger(getClass().getName());
// define a bean for ViewResolver
#Bean
public DataSource myDataSource() {
// create connection pool
ComboPooledDataSource myDataSource = new ComboPooledDataSource();
// set the jdbc driver
try {
myDataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
}
catch (PropertyVetoException exc) {
throw new RuntimeException(exc);
}
// for sanity's sake, let's log url and user ... just to make sure we are reading the data
logger.info("jdbc.url=" + env.getProperty("spring.datasource.url"));
logger.info("jdbc.user=" + env.getProperty("spring.datasource.username"));
// set database connection props
myDataSource.setJdbcUrl(env.getProperty("spring.datasource.url"));
myDataSource.setUser(env.getProperty("spring.datasource.username"));
myDataSource.setPassword(env.getProperty("spring.datasource.password"));
// set connection pool props
myDataSource.setInitialPoolSize(getIntProperty("connection.pool.initialPoolSize"));
myDataSource.setMinPoolSize(getIntProperty("connection.pool.minPoolSize"));
myDataSource.setMaxPoolSize(getIntProperty("connection.pool.maxPoolSize"));
myDataSource.setMaxIdleTime(getIntProperty("connection.pool.maxIdleTime"));
return myDataSource;
}
private Properties getHibernateProperties() {
// set hibernate properties
Properties props = new Properties();
props.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
props.setProperty("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
props.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
return props;
}
// need a helper method
// read environment property and convert to int
private int getIntProperty(String propName) {
String propVal = env.getProperty(propName);
// now convert to int
int intPropVal = Integer.parseInt(propVal);
return intPropVal;
}
#Bean
public LocalSessionFactoryBean sessionFactory(){
// create session factorys
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
// set the properties
sessionFactory.setDataSource(myDataSource());
sessionFactory.setPackagesToScan(env.getProperty("hibernate.packagesToScan"));
sessionFactory.setHibernateProperties(getHibernateProperties());
return sessionFactory;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
// setup transaction manager based on session factory
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(sessionFactory);
return txManager;
}
#Bean
public ModelMapper modelMapper() {
return new ModelMapper();
}
#Bean
public ConfigManagement configManagement() {
return new ConfigManagement();
}
}
And the Spring Boot main():
#Configuration
#EnableWebMvc
#EnableTransactionManagement
#ComponentScan("com.cybertrust.tms")
//#PropertySource({ "classpath:persistence-mysql.properties" })
#PropertySource({ "classpath:model.properties" })
//#EnableAutoConfiguration(exclude = HibernateJpaAutoConfiguration.class)
#SpringBootApplication(exclude = {HibernateJpaAutoConfiguration.class})
public class TMS extends SpringBootServletInitializer {
public static void main(String[] args) throws Exception {
SpringApplication.run(TMS.class, args);
}
}
Your static solution won't work in a Spring environment as is, because static can be executed before Spring is up and loaded all beans and properties
You should rewrite your code in a Spring way by getting propertyies using #Value
Injecting a property with the #Value annotation is straightforward:
#Value( "${jdbc.url}" )
private String jdbcUrl;
In order to integrate this code to a Spring project, I had to:
Make the class a bean, managed by Spring, by adding it in my configuration file that I posted in my question, I added this:
#Bean
public ConfigManagement configManagement() {
return new ConfigManagement();
}
Remove the static declaration from the class properties and use the #Value annotation to initialize them from the application.properties file, as suggested by #user7294900.
However, some of the class properties were not primitive types and couldn't be initialized directly from the application.properties. They needed some "business-logic" to be run at initialization time. In order to achieve that, I had to remove the static declaration and add the #PostConstruct annotation in the initializeConfig() method, which is the one that handled the initialization of the rest of the properties.
public class ConfigManagement {
#Value("${cybertrust.crypto.signatureAlgorithm}")
private String signatureAlgorithm;
#Value("${cybertrust.crypto.myName}")
private String myName;
#Value("${cybertrust.crypto.myCertificate}")
private String myCertificate;
#Value("${cybertrust.crypto.myPrivateKey}")
private String myPrivateKey;
private RSAPublicKey myRSAPublicKey;
private RSAPrivateKey myRSAPrivateKey;
private HashMap<String, RSAPublicKey> peerPubKeys = new HashMap<String, RSAPublicKey>();
private boolean isInitialized = false;
int peerCounter;
/**
* #return the signatureAlgorithm
*/
public ConfigManagement() {
}
#PostConstruct
public void initializeConfig() throws Exception {
try {
try {
myRSAPublicKey = Loader.getPublicKeyFromCertificateFile("C:\\Users\\Findorgri\\git\\trust-management\\TMS-rest\\" + myCertificate);
}
catch (Exception e) {
throw new IllegalStateException("cybertrust.crypto.myCertificate is empty, the file is not found or it contains invalid data");
}
try {
myRSAPrivateKey = Loader.getPrivateKeyFromFile("C:\\Users\\Findorgri\\git\\trust-management\\TMS-rest\\" + myPrivateKey);
}
catch (Exception e) {
throw new IllegalStateException("cybertrust.crypto.myPrivateKey is empty, the file is not found or it contains invalid data");
}
peerPubKeys.put(myName, myRSAPublicKey);
Properties props = loadProperties("C:\\Users\\Findorgri\\git\\trust-management\\TMS-rest\\src\\main\\resources\\application.properties");
if (props == null) {
throw new Exception("Properties file not found");
}
peerCounter = 0;
do {
String peerNameProp = String.format("cybertrust.crypto.peerModules.%d.name", peerCounter);
String peerName = props.getProperty(peerNameProp);
System.out.println("####TEST####\n" + peerNameProp + "\n" + peerName +"\n####TEST####");
if (peerName == null)
break;
String peerNameCertFileProp = String.format("cybertrust.crypto.peerModules.%d.certificate", peerCounter);
String peerNameCertFile = props.getProperty(peerNameCertFileProp);
System.out.println("####TEST####\n" + peerNameCertFileProp + "\n" + peerNameCertFile +"\n####TEST####");
if (peerNameCertFile == null) // Do not halt the program, produce though an error
Logger.getLogger("ConfigManagement").log(Level.SEVERE,
String.format("Property %s not found while property %s is defined", peerNameCertFile, peerNameProp));
// instantiate public key from file
try {
RSAPublicKey peerRsaPubKey = Loader.getPublicKeyFromCertificateFile("C:\\Users\\Findorgri\\git\\trust-management\\TMS-rest\\" + peerNameCertFile);
peerPubKeys.put(peerName, peerRsaPubKey);
}
catch (Exception e) {
Logger.getLogger("ConfigManagement").log(Level.SEVERE,
String.format("File %s specified in property %s not found or does not contains a valid RSA key", peerNameCertFile, peerNameCertFileProp)); }
peerCounter++;
} while (true);
}
catch (Exception e) {
throw(e);
}
if ((myRSAPublicKey == null) || (signatureAlgorithm == null) || (myName == null))
throw new IllegalStateException("one of the properties cybertrust.crypto.signatureAlgorithm, cybertrust.crypto.myName, cybertrust.crypto.myPublicKey, cybertrust.crypto.myPrivateKey is not defined");
isInitialized = true;
peerPubKeys.forEach((key, value) -> System.out.println(key + ":" + value));
}
....
Finally, for completeness' sake, for the initializeConfig() method to have access at the application.properties I had to use this method:
private static Properties loadProperties(String fileName) throws IOException {
FileInputStream fis = null;
Properties prop = null;
try {
fis = new FileInputStream(fileName);
prop = new Properties();
prop.load(fis);
} catch(FileNotFoundException fnfe) {
fnfe.printStackTrace();
} catch(IOException ioe) {
ioe.printStackTrace();
} finally {
fis.close();
}
return prop;
}

How to upload a new version of a file by using WebScript?

I have a simple Spring application (front-end application) that loads files into the Alfresco repository. If the file already exists, its new version is not created.
Repository web script is presented below:
public class CustomFileUploader extends DeclarativeWebScript {
private static final String FIRM_DOC =
"{http://www.firm.com/model/content/1.0}someDoc";
private static final String FIRM_DOC_FOLDER =
"workspace://SpacesStore/8caf07c3-6aa9-4a41-bd63-404cb3e3ef0f";
private FirmFile firmFile;
private FileFolderService fileFolderService;
private ContentService contentService;
protected Map<String, Object> executeImpl(WebScriptRequest req,
Status status) {
retrievePostRequestParams(req);
writeContent();
return null;
}
private void retrievePostRequestParams(WebScriptRequest req) {
FormData formData = (FormData) req.parseContent();
FormData.FormField[] fields = formData.getFields();
for(FormData.FormField field : fields) {
String fieldName = field.getName();
String fieldValue = field.getValue();
if(fieldName.equalsIgnoreCase("firm_file")
&& field.getIsFile()) {
String fileName = field.getFilename();
Content fileContent = field.getContent();
String fileMimetype = field.getMimetype();
firmFile = new FirmFile(fileName, fileContent,
fileMimetype, FIRM_DOC);
}
}
}
private void writeContent() {
try {
NodeRef parentNodeRef = new NodeRef(FIRM_DOC_FOLDER);
NodeRef fileNodeRef = createFileNode(parentNodeRef,
firmFile.getFileName());
ContentWriter contentWriter = contentService.getWriter(fileNodeRef,
ContentModel.PROP_CONTENT, true);
contentWriter.setMimetype(firmFile.getFileMimetype());
contentWriter.putContent(firmFile.getFileContent().getInputStream());
} catch (Exception e) {
e.printStackTrace();
}
}
private NodeRef createFileNode(NodeRef parentNode, String fileName) {
try {
QName contentQName = QName.createQName(FIRM_DOC);
FileInfo fileInfo = fileFolderService.create(parentNode,
fileName, contentQName);
return fileInfo.getNodeRef();
} catch (Exception e) {
e.printStackTrace();
}
}
public FileFolderService getFileFolderService() {
return fileFolderService;
}
public void setFileFolderService(FileFolderService fileFolderService) {
this.fileFolderService = fileFolderService;
}
public ContentService getContentService() {
return contentService;
}
public void setContentService(ContentService contentService) {
this.contentService = contentService;
}
}
How to create a new version of a file with the same name by using Java-backed WebScript?
Does this solution correct?
Check if the file exists by using Lucene search: TYPE:"firm:doc" AND #cm\:name:contract.png; (for example) If exists, increment the property cm:versionLabel and create a new version of Node with all the properties (Actually, need to iterate through all the ResultSet and find NodeRef with max value of cm:versionLabel then increment it and create a new Node). Is there more elegant solution?
The solution can be represented as follows:
public class CustomFileUploader extends DeclarativeWebScript {
private static final String FIRM_DOC = "{http://www.firm.com/model/content/1.0}doc";
private static final String FIRM_DOC_FOLDER = "workspace://SpacesStore/8caf07c3-6aa9-4a41-bd63-404cb3e3ef0f";
private FileFolderService fileFolderService;
private ContentService contentService;
private NodeService nodeService;
private SearchService searchService;
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status) {
processUpload(req);
return null;
}
private void writeContent(NodeRef node, FirmFile firmFile) {
try {
ContentWriter contentWriter = contentService.getWriter(node, ContentModel.PROP_CONTENT, true);
contentWriter.setMimetype(firmFile.getFileMimetype());
contentWriter.putContent(firmFile.getFileContent().getInputStream());
} catch (Exception e) {
e.printStackTrace();
}
}
private NodeRef checkIfNodeExists(String fileName) {
StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore");
ResultSet resultSet = searchService.query(storeRef, SearchService.LANGUAGE_LUCENE/*LANGUAGE_FTS_ALFRESCO*/,
"TYPE:\"firm:doc\" AND #cm\\:name:" + fileName.replaceAll(" ", "\\ ")+ "");
int len = resultSet.length();
if(len == 0) {
return null;
}
NodeRef node = resultSet.getNodeRef(0);
return node;
}
private NodeRef createNewNode(FirmFile firmFile) {
NodeRef parent = new NodeRef(FIRM_DOC_FOLDER);
NodeRef node = createFileNode(parent, firmFile.getFileName());
return node;
}
private void processUpload(WebScriptRequest req) {
FormData formData = (FormData) req.parseContent();
FormData.FormField[] fields = formData.getFields();
for(FormData.FormField field : fields) {
String fieldName = field.getName();
if(fieldName.equalsIgnoreCase("firm_file") && field.getIsFile()) {
String fileName = field.getFilename();
Content fileContent = field.getContent();
String fileMimetype = field.getMimetype();
NodeRef node = checkIfNodeExists(fileName);
// POJO
FirmFile firm = new FirmFile(fileName, fileContent, fileMimetype, FIRM_DOC);
if(node == null) {
node = createNewNode(firmFile);
}
writeContent(node, firmFile);
}
}
}
private NodeRef createFileNode(NodeRef parentNode, String fileName) {
try {
QName contentQName = QName.createQName(FIRM_DOC);
FileInfo fileInfo = fileFolderService.create(parentNode, fileName, contentQName);
return fileInfo.getNodeRef();
} catch (Exception e) {
e.printStackTrace();
}
}
public FileFolderService getFileFolderService() {
return fileFolderService;
}
public void setFileFolderService(FileFolderService fileFolderService) {
this.fileFolderService = fileFolderService;
}
public ContentService getContentService() {
return contentService;
}
public void setContentService(ContentService contentService) {
this.contentService = contentService;
}
public NodeService getNodeService() {
return nodeService;
}
public void setNodeService(NodeService nodeService) {
this.nodeService = nodeService;
}
public SearchService getSearchService() {
return searchService;
}
public void setSearchService(SearchService searchService) {
this.searchService = searchService;
}
}
The content model must have a mandatory aspect cm:versionable:
<mandatory-aspects>
<aspect>cm:versionable</aspect>
</mandatory-aspects>

NoSuchBeanDefinitionException when trying to get defined Component

I have a problem with getting a bean from application context when using Spring IoC.
I have a ContactProvider interface for my phone book application and 3 implementations of this interface. All implementations are Spring #Components. I also have a Preferences which stores which of the implementation is used by the user. When the user tries to change the implementation the application throws NoSuchBeanDefinitionException. To find out which implementation the user wants to use based on his input I created utility enum with all of my implementations that provides Class objects for all of the implementation. This class has fromString() method which returns implementation type based on given string (which is user input).
Method for setting a new contact provider:
private void handleSetProviderCommand(String param) {
ContactProviders providerType = ContactProviders.fromString(param);
Class<? extends ContactProvider> providerClass = providerType.getProviderClass();
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
ContactProvider contactProvider = context.getBean(providerClass); // I get NoSuchBeanDefinitionException here
phoneBook.setContactProvider(contactProvider);
Preferences preferences = Preferences.userNodeForPackage(PhoneBook.class);
preferences.put(PreferenceKeys.CONTACT_PROVIDER.getKey(), param);
}
ContactProviders enum, from which I take a class of the implementation:
public enum ContactProviders {
FILE(FileContactProvider.SHORT_NAME, FileContactProvider.class),
ELASTIC(ElasticContactProvider.SHORT_NAME, ElasticContactProvider.class),
NO_SQL(NoSqlContactProvider.SHORT_NAME, NoSqlContactProvider.class);
private final Class<? extends ContactProvider> providerClass;
private final String shortName;
ContactProviders(String shortName, Class<? extends ContactProvider> providerClass) {
this.shortName = shortName;
this.providerClass = providerClass;
}
public static ContactProviders fromString(String param) {
Optional<ContactProviders> providerType = Arrays.stream(ContactProviders.values())
.filter(cp -> cp.getShortName().equals(param)).findFirst();
if (providerType.isPresent()) {
return providerType.get();
} else {
throw new IllegalArgumentException("Contact provider not recognized: " + param);
}
}
}
One of the implementations (all of them are annotated with #Component):
public class FileContactProvider implements ContactProvider {
public static final String SHORT_NAME = "file";
private static final String SEPARATOR = "|";
private List<Contact> contacts;
private Path file;
private Logger logger = LoggerFactory.getLogger(FileContactProvider.class);
public FileContactProvider() {
file = openFile();
contacts = loadContacts();
}
private Path openFile() {
Preferences preferences = Preferences.userNodeForPackage(FileContactProvider.class);
Path file = Paths.get(
preferences.get(
PreferenceKeys.FILE_FILE_NAME.getKey(),
PreferenceKeys.FILE_FILE_NAME.getDefaultValue()
)
);
if (Files.exists(file)) {
try {
if (Files.isReadable(file) && Files.isWritable(file)) {
return file;
} else {
throw new IOException("The file is not readable or writable.");
}
} catch (IOException e) {
logger.error("Error while opening the file: " + e.getMessage());
}
} else {
try {
Files.createFile(file);
} catch (IOException e) {
logger.error("Error while creating a file: " + e.getMessage());
}
}
return file;
}
private void saveFile() {
List<String> contactStrings = new ArrayList<>();
contacts.stream()
.sorted()
.forEach(contact -> contactStrings.add(contact.getName() + SEPARATOR + contact.getNumber()));
try {
Files.write(file, contactStrings);
} catch (IOException e) {
logger.error("Error while saving to the file: " + e.getMessage());
}
}
private List<Contact> loadContacts() {
List<Contact> loaded = new ArrayList<>();
try {
Files.readAllLines(file)
.forEach(line -> {
String[] contactString = StringUtils.split(line, SEPARATOR);
Contact contact = new Contact(contactString[0], contactString[1]);
loaded.add(contact);
});
} catch (IOException e) {
logger.error("Error while reading file content: " + e.getMessage());
}
return loaded;
}
#Override
public Contact save(Contact contact) {
if (contacts.contains(contact)) {
System.out.println("Contact is already in the phone book.");
} else {
contacts.add(contact);
saveFile();
}
return contact;
}
#Override
public List<Contact> find(String name) throws ContactNotFoundException {
List<Contact> found = contacts.stream()
.filter(contact -> StringUtils.indexOf(contact.getName().toLowerCase(), name.toLowerCase()) != -1)
.collect(Collectors.toList());
if (found.isEmpty()) {
throw new ContactNotFoundException(name);
}
return found;
}
#Override
public List<Contact> getAll() {
return contacts;
}
#Override
public void delete(Contact contact) {
contacts.remove(contact);
saveFile();
}
#Override
public void configure() {
System.out.print("Enter file name: ");
String filename = ConsoleUtils.getInput("^[^<>:;,?\"*|/]+$");
Preferences preferences = Preferences.userNodeForPackage(FileContactProvider.class);
preferences.put(PreferenceKeys.FILE_FILE_NAME.getKey(), filename);
file = openFile();
contacts = loadContacts();
}
#Override
public void showConfiguration() {
Preferences preferences = Preferences.userNodeForPackage(FileContactProvider.class);
System.out.println("File name: " +
preferences.get(
PreferenceKeys.FILE_FILE_NAME.getKey(),
PreferenceKeys.FILE_FILE_NAME.getDefaultValue()
)
);
}
}
I also have a bean defined in my #Configuration class to provide a contact provider based on preference already set in the system. It takes preference string and creates an instance of implementation class to return:
#Bean
public ContactProvider contactProvider() {
Preferences preferences = Preferences.userNodeForPackage(PhoneBook.class);
String preferredProviderName = preferences.get(PreferenceKeys.CONTACT_PROVIDER.toString(),
ContactProviders.FILE.getShortName());
try {
Class<? extends ContactProvider> providerClass = ContactProviders.fromString(preferredProviderName)
.getProviderClass();
Constructor<? extends ContactProvider> constructor = providerClass.getConstructor();
return constructor.newInstance();
} catch (IllegalArgumentException e) {
logger.error("Can't get provider from given string: " + e.getMessage());
} catch (NoSuchMethodException e) {
logger.error("Can't find provider's constructor: " + e.getMessage());
} catch (IllegalAccessException e) {
logger.error("Can't get access to provider's constructor: " + e.getMessage());
} catch (InstantiationException e) {
logger.error("Can instantiate provider: " + e.getMessage());
} catch (InvocationTargetException e) {
logger.error("Can't invoke provider's constructor: " + e.getMessage());
}
logger.info("Couldn't get provider from preferences. Default file contact provider instantiated.");
return new FileContactProvider();
}

Could not render red5 recorded media stream

I have problem of playing back the recorded media file from red5 published stream, following is my code. I could see a file called out.flv is created, but this out.flv can not be played back.
public class Red5ClientTest {
private static Timer timer;
private static RTMPClient client;
private static String sourceStreamName;
private static int videoTs;
private static int audioTs;
private static FLVWriter writer;
private static int bytesRead =0;
public static void main(String[] args) throws IOException {
String sourceHost = "localhost";
int sourcePort = 1935;
String sourceApp = "oflaDemo";
sourceStreamName = "myStream";
timer = new Timer();
client = new RTMPClient();
String path = "c:\\temp\\out.flv";
File file = new File(path);
if (!file.exists()) {
file.createNewFile();
}
writer = new FLVWriter(file,true);
client.setStreamEventDispatcher(new StreamEventDispatcher());
client.setStreamEventHandler(new INetStreamEventHandler() {
public void onStreamEvent(Notify notify) {
System.out.printf("onStreamEvent: %s\n", notify);
ObjectMap<?, ?> map = (ObjectMap<?, ?>) notify.getCall().getArguments()[0];
String code = (String) map.get("code");
System.out.printf("<:%s\n", code);
if (StatusCodes.NS_PLAY_STREAMNOTFOUND.equals(code)) {
System.out.println("Requested stream was not found");
client.disconnect();
}
else if (StatusCodes.NS_PLAY_UNPUBLISHNOTIFY.equals(code)
|| StatusCodes.NS_PLAY_COMPLETE.equals(code)) {
System.out.println("Source has stopped publishing or play is complete");
client.disconnect();
}
}
});
client.setConnectionClosedHandler(new Runnable() {
public void run() {
if (writer != null) {
writer.close();
}
System.out.println("Source connection has been closed, proxy will be stopped");
System.exit(0);
}
});
client.setExceptionHandler(new ClientExceptionHandler() {
#Override
public void handleException(Throwable throwable) {
throwable.printStackTrace();
System.exit(1);
}
});
// connect the consumer
Map<String, Object> defParams = client.makeDefaultConnectionParams(sourceHost, sourcePort,
sourceApp);
// add pageurl and swfurl
defParams.put("pageUrl", "");
defParams.put("swfUrl", "app:/Red5-StreamRelay.swf");
// indicate for the handshake to generate swf verification data
client.setSwfVerification(true);
// connect the client
client.connect(sourceHost, sourcePort, defParams, new IPendingServiceCallback() {
public void resultReceived(IPendingServiceCall call) {
System.out.println("connectCallback");
ObjectMap<?, ?> map = (ObjectMap<?, ?>) call.getResult();
String code = (String) map.get("code");
if ("NetConnection.Connect.Rejected".equals(code)) {
System.out.printf("Rejected: %s\n", map.get("description"));
client.disconnect();
//proxy.stop();
}
else if ("NetConnection.Connect.Success".equals(code)) {
// 1. Wait for onBWDone
timer.schedule(new BandwidthStatusTask(), 2000L);
Object result = call.getResult();
System.out.println("Red5ClientTest.main()");
}
else {
System.out.printf("Unhandled response code: %s\n", code);
}
}
});
// keep sleeping main thread while the proxy runs
// kill the timer
//timer.cancel();
System.out.println("Stream relay exit");
}
/**
* Handles result from subscribe call.
*/
private static final class SubscribeStreamCallBack implements IPendingServiceCallback {
public void resultReceived(IPendingServiceCall call) {
System.out.println("resultReceived: " + call);
Object result = call.getResult();
System.out.println("results came {}" + result);
}
}
private static final class StreamEventDispatcher implements IEventDispatcher {
public void dispatchEvent(IEvent event) {
System.out.println("ClientStream.dispachEvent()" + event.toString());
try {
//RTMPMessage build = RTMPMessage.build((IRTMPEvent) event);
IRTMPEvent rtmpEvent = (IRTMPEvent) event;
ITag tag = new Tag();
tag.setDataType(rtmpEvent.getDataType());
if (rtmpEvent instanceof VideoData) {
videoTs += rtmpEvent.getTimestamp();
tag.setTimestamp(videoTs);
}
else if (rtmpEvent instanceof AudioData) {
audioTs += rtmpEvent.getTimestamp();
tag.setTimestamp(audioTs);
}
IoBuffer data = ((IStreamData) rtmpEvent).getData().asReadOnlyBuffer();
tag.setBodySize(data.limit());
tag.setBody(data);
try {
writer.writeTag(tag);
} catch (Exception e) {
throw new RuntimeException(e);
}
System.out.println("writting....");
}
catch (Exception e) {//IOException
e.printStackTrace();
}
}
}
private static final class BandwidthStatusTask extends TimerTask {
#Override
public void run() {
// check for onBWDone
System.out.println("Bandwidth check done: " + client.isBandwidthCheckDone());
// cancel this task
this.cancel();
// create a task to wait for subscribed
timer.schedule(new PlayStatusTask(), 1000L);
// 2. send FCSubscribe
client.subscribe(new SubscribeStreamCallBack(), new Object[] { sourceStreamName });
}
}
private static final class PlayStatusTask extends TimerTask {
#Override
public void run() {
// checking subscribed
System.out.println("Subscribed: " + client.isSubscribed());
// cancel this task
this.cancel();
// 3. create stream
client.createStream(new CreateStreamCallback());
}
}
/**
* Creates a "stream" via playback, this is the source stream.
*/
private static final class CreateStreamCallback implements IPendingServiceCallback {
public void resultReceived(IPendingServiceCall call) {
System.out.println("resultReceived: " + call);
int streamId = ((Number) call.getResult()).intValue();
System.out.println("stream id: " + streamId);
// send our buffer size request
if (sourceStreamName.endsWith(".flv") || sourceStreamName.endsWith(".f4v")
|| sourceStreamName.endsWith(".mp4")) {
client.play(streamId, sourceStreamName, 0, -1);
}
else {
client.play(streamId, sourceStreamName, -1, 0);
}
}
}
}
what could I be doing possibly wrong here?
Finally got it
public class TeqniRTMPClient {
private static final Logger logger = LoggerFactory.getLogger(MyRtmpClient.class);
public static void main(String args[]) throws IOException {
TeqniRTMPClient client = new TeqniRTMPClient("localhost", 1935, "oflaDemo", "myStream");
client.recordStream();
}
private RTMPClient client;
private ITagWriter writer;
private String sourceHost;
private int sourcePort;
private String sourceApp;
private String sourceStreamName;
private int lastTimestamp;
private int startTimestamp = -1;
public TeqniRTMPClient(String sourceHost, int sourcePort, String sourceApp,
String sourceStreamName) {
super();
this.sourceHost = sourceHost;
this.sourcePort = sourcePort;
this.sourceApp = sourceApp;
this.sourceStreamName = sourceStreamName;
}
public void recordStream() throws IOException {
client = new RTMPClient();
String path = "c:\\temp\\out.flv";
File file = new File(path);
if (!file.exists()) {
file.createNewFile();
}
FLVService flvService = new FLVService();
flvService.setGenerateMetadata(true);
try {
IStreamableFile flv = flvService.getStreamableFile(file);
writer = flv.getWriter();
}
catch (Exception e) {
throw new RuntimeException(e);
}
client.setStreamEventDispatcher(new StreamEventDispatcher());
client.setStreamEventHandler(new INetStreamEventHandler() {
public void onStreamEvent(Notify notify) {
System.out.printf("onStreamEvent: %s\n", notify);
ObjectMap<?, ?> map = (ObjectMap<?, ?>) notify.getCall().getArguments()[0];
String code = (String) map.get("code");
System.out.printf("<:%s\n", code);
if (StatusCodes.NS_PLAY_STREAMNOTFOUND.equals(code)) {
System.out.println("Requested stream was not found");
client.disconnect();
}
else if (StatusCodes.NS_PLAY_UNPUBLISHNOTIFY.equals(code)
|| StatusCodes.NS_PLAY_COMPLETE.equals(code)) {
System.out.println("Source has stopped publishing or play is complete");
client.disconnect();
}
}
});
client.setExceptionHandler(new ClientExceptionHandler() {
#Override
public void handleException(Throwable throwable) {
throwable.printStackTrace();
System.exit(1);
}
});
client.setConnectionClosedHandler(new Runnable() {
public void run() {
if (writer != null) {
writer.close();
}
System.out.println("Source connection has been closed, proxy will be stopped");
System.exit(0);
}
});
// connect the consumer
Map<String, Object> defParams = client.makeDefaultConnectionParams(sourceHost, sourcePort,
sourceApp);
// add pageurl and swfurl
defParams.put("pageUrl", "");
defParams.put("swfUrl", "app:/Red5-StreamRelay.swf");
// indicate for the handshake to generate swf verification data
client.setSwfVerification(true);
// connect the client
client.connect(sourceHost, sourcePort, defParams, new IPendingServiceCallback() {
public void resultReceived(IPendingServiceCall call) {
System.out.println("connectCallback");
ObjectMap<?, ?> map = (ObjectMap<?, ?>) call.getResult();
String code = (String) map.get("code");
if ("NetConnection.Connect.Rejected".equals(code)) {
System.out.printf("Rejected: %s\n", map.get("description"));
client.disconnect();
}
else if ("NetConnection.Connect.Success".equals(code)) {
// 1. Wait for onBWDone
client.createStream(new CreateStreamCallback());
Object result = call.getResult();
System.out.println("Red5ClientTest.main()");
}
else {
System.out.printf("Unhandled response code: %s\n", code);
}
}
});
}
class CreateStreamCallback implements IPendingServiceCallback {
public void resultReceived(IPendingServiceCall call) {
System.out.println("resultReceived: " + call);
int streamId = ((Number) call.getResult()).intValue();
System.out.println("stream id: " + streamId);
// send our buffer size request
if (sourceStreamName.endsWith(".flv") || sourceStreamName.endsWith(".f4v")
|| sourceStreamName.endsWith(".mp4")) {
client.play(streamId, sourceStreamName, 0, -1);
}
else {
client.play(streamId, sourceStreamName, -1, 0);
}
}
}
class StreamEventDispatcher implements IEventDispatcher {
private int videoTs;
private int audioTs;
public void dispatchEvent(IEvent event) {
System.out.println("ClientStream.dispachEvent()" + event.toString());
try {
IRTMPEvent rtmpEvent = (IRTMPEvent) event;
logger.debug("rtmp event: " + rtmpEvent.getHeader() + ", "
+ rtmpEvent.getClass().getSimpleName());
if (!(rtmpEvent instanceof IStreamData)) {
logger.debug("skipping non stream data");
return;
}
if (rtmpEvent.getHeader().getSize() == 0) {
logger.debug("skipping event where size == 0");
return;
}
byte dataType = rtmpEvent.getDataType();
ITag tag = new Tag();
tag.setDataType(dataType);
if (rtmpEvent instanceof VideoData) {
VideoData video = (VideoData) rtmpEvent;
FrameType frameType = video.getFrameType();
videoTs += rtmpEvent.getTimestamp();
tag.setTimestamp(videoTs);
}
else if (rtmpEvent instanceof AudioData) {
audioTs += rtmpEvent.getTimestamp();
tag.setTimestamp(audioTs);
}
IoBuffer data = ((IStreamData) rtmpEvent).getData().asReadOnlyBuffer();
tag.setBodySize(data.limit());
tag.setBody(data);
try {
writer.writeTag(tag);
}
catch (Exception e) {
throw new RuntimeException(e);
}
System.out.println("writting....");
}
catch (Exception e) {//IOException
e.printStackTrace();
}
}
}
}

Categories

Resources