001 package opendreams.proxy;
002
003 import java.io.FileInputStream;
004 import java.io.FileNotFoundException;
005 import java.io.InputStream;
006 import java.io.Reader;
007 import java.security.cert.X509Certificate;
008 import java.security.interfaces.RSAPrivateKey;
009 import java.util.Properties;
010 import java.util.logging.Level;
011
012 import openbusidl.rs.IRegistryService;
013 import openbusidl.rs.Property;
014 import openbusidl.rs.ServiceOffer;
015
016 import org.omg.CORBA_2_3.ORB;
017
018 import scs.core.IComponent;
019 import tecgraf.openbus.Openbus;
020 import tecgraf.openbus.DRMAA.JobInfoHelper;
021 import tecgraf.openbus.data_service.DataAccessDenied;
022 import tecgraf.openbus.data_service.DataDescription;
023 import tecgraf.openbus.data_service.IHierarchicalDataService;
024 import tecgraf.openbus.data_service.IHierarchicalDataServiceHelper;
025 import tecgraf.openbus.data_service.ServiceFailure;
026 import tecgraf.openbus.data_service.UnstructuredDataFactory;
027 import tecgraf.openbus.data_service.UnstructuredDataHelper;
028 import tecgraf.openbus.opendreams.IOpenDreams;
029 import tecgraf.openbus.opendreams.IOpenDreamsHelper;
030 import tecgraf.openbus.opendreams.JobInfoFactory;
031 import tecgraf.openbus.opendreams.JobParameterFactory;
032 import tecgraf.openbus.opendreams.JobParameterHelper;
033 import tecgraf.openbus.opendreams.OpenDreamsJobTemplateFactory;
034 import tecgraf.openbus.opendreams.OpenDreamsJobTemplateHelper;
035 import tecgraf.openbus.project.ProjectItemDescription;
036 import tecgraf.openbus.project.ProjectItemDescriptionFactory;
037 import tecgraf.openbus.project.ProjectItemDescriptionHelper;
038 import tecgraf.openbus.util.CryptoUtils;
039 import tecgraf.openbus.util.Log;
040
041 /**
042 * O <code>OpenDreamsProxy</code> tem como objetivo encapsular os mecanismos
043 * de acesso ao OpenDreams. Faz o login no barramento e recupara as interfaces
044 * dos serviços usados pelo cliente desse barramento.
045 *
046 * @author Tecgraf PUC-Rio
047 */
048 public class OpenDreamsProxy {
049 /**
050 * Nome do arquivo default com as propriedades para acesso ao OpenDreams.
051 */
052 public static String DEFAULT_PROPERTIES_FILE = "opendreams.properties";
053
054 private IRegistryService registryService;
055 private IOpenDreams opendreams;
056 private IHierarchicalDataService dataService;
057 private OpenDreamsProperties properties = null;
058
059 /**
060 * Constrói um proxy para o serviço OpenDreams do OpenBus, usando as
061 * propriedades especificadas.
062 *
063 * @param properties as propriedades previamente configuradas
064 * @see opendreams.proxy.OpenDreamsProperties#PROPERTIES
065 * @throws OpenDreamsException se houve falha na carga das propriedades
066 */
067 public OpenDreamsProxy(Properties properties) throws OpenDreamsException {
068 this.properties = new OpenDreamsProperties(properties);
069 }
070
071 /**
072 * Constrói um proxy para o serviço OpenDreams do OpenBus, usando as
073 * propriedades do arquivo default de propriedades
074 *
075 * @see opendreams.proxy.OpenDreamsProperties#PROPERTIES
076 * @see #DEFAULT_PROPERTIES_FILE
077 * @see #loadProperties(InputStream)
078 * @see #loadProperties(Reader)
079 * @throws OpenDreamsException se houve falha na carga das propriedades
080 */
081 public OpenDreamsProxy() throws OpenDreamsException {
082 try {
083 loadProperties(new FileInputStream(DEFAULT_PROPERTIES_FILE));
084 }
085 catch (FileNotFoundException e) {
086 throw new OpenDreamsException(
087 "Arquivo de propriedades default jacorb.properties" + " não encontrado",
088 e);
089 }
090 }
091
092 /**
093 * Carrega as propriedades para acesso ao OpenDreams.
094 *
095 * @param propertiesFile objeto <code>InputStream</code> com as propriedades
096 * @throws OpenDreamsException se houve falha na carga das propriedades
097 */
098 protected void loadProperties(InputStream propertiesFile)
099 throws OpenDreamsException {
100 this.properties = new OpenDreamsProperties(propertiesFile);
101 }
102
103 /**
104 * Carrega as propriedades para acesso ao OpenDreams.
105 *
106 * @param propertiesFile objeto <code>Reader</code> com as propriedades
107 * @throws OpenDreamsException se houve falha na carga das propriedades
108 */
109 protected void loadProperties(Reader propertiesFile)
110 throws OpenDreamsException {
111 this.properties = new OpenDreamsProperties(propertiesFile);
112 }
113
114 /**
115 * Iniciliza o contexto de acesso ao barramento.
116 *
117 * @throws OpenDreamsException falha no acesso ao openbus
118 */
119 public void init() throws OpenDreamsException {
120 if (properties == null) {
121 throw new OpenDreamsException("Propriedades não definidas");
122 }
123 Log.setLogsLevel(Level.WARNING);
124 try {
125 Properties orbProps = new Properties();
126 orbProps.setProperty("org.omg.CORBA.ORBClass", properties.getORBClass());
127 orbProps.setProperty("org.omg.CORBA.ORBSingletonClass", properties
128 .getORBSingletonClass());
129 Openbus bus = Openbus.getInstance();
130 bus.resetAndInitialize(new String[] {}, orbProps, properties.getHost(),
131 properties.getPort());
132 String acsCertificateFile = properties.getCertificate();
133 RSAPrivateKey privateKey =
134 CryptoUtils.readPrivateKey(properties.getPrivateKey());
135 X509Certificate acsCertificate =
136 CryptoUtils.readCertificate(acsCertificateFile);
137 registryService =
138 bus.connect(properties.getEntityName(), privateKey, acsCertificate);
139 if (properties.hasDelegation()) {
140 String delegateToUser = properties.getDelegate();
141 bus.getCredential().delegate = delegateToUser;
142 }
143 }
144 catch (Exception e) {
145 throw new OpenDreamsException("Erro no acesso ao OpenBus: "
146 + properties.getHost() + " " + properties.getPort(), e);
147 }
148 registerFactories();
149 }
150
151 /**
152 * Obtém o objeto registrado no openbus que implementa a interface
153 * <code>IOpenDreams</code>
154 *
155 * @return o serviço <code>IOpenDreams</code>
156 * @throws OpenDreamsException se o serviço não foi encontrado
157 */
158 public IOpenDreams getIOpenDreams() throws OpenDreamsException {
159 if (opendreams == null) {
160 String componentId =
161 getComponentId(properties.getOpenDreamsComponentName().trim(),
162 properties.getOpenDreamsComponentVersion().trim());
163 Property property =
164 new Property("component_id", new String[] { componentId });
165 ServiceOffer[] servicesOffers =
166 registryService.findByCriteria(new String[] { "opendreams" },
167 new Property[] { property });
168 if (servicesOffers.length == 0) {
169 throw new OpenDreamsException("Não foi encontrado um serviço com "
170 + "identificador: " + componentId);
171 }
172 if (servicesOffers.length > 1) {
173 throw new OpenDreamsException("Foi encontrado mais de um serviço com "
174 + "identificador: " + componentId);
175 }
176 ServiceOffer serviceOffer = servicesOffers[0];
177 IComponent component = serviceOffer.member;
178 org.omg.CORBA.Object opendreamsObject =
179 component.getFacet(IOpenDreamsHelper.id());
180 opendreams = IOpenDreamsHelper.narrow(opendreamsObject);
181 }
182 return opendreams;
183 }
184
185 /**
186 * Obtém o objeto registrado no openbus que implementa a interface
187 * <code>IOpenDreams</code>
188 *
189 * @return o serviço <code>IOpenDreams</code>
190 * @throws OpenDreamsException se o serviço não foi encontrado
191 */
192 public IHierarchicalDataService getIDataService() throws OpenDreamsException {
193 if (dataService == null) {
194 String componentId =
195 getComponentId(properties.getDataServiceComponentName().trim(),
196 properties.getDataServiceComponentVersion().trim());
197 Property property =
198 new Property("component_id", new String[] { componentId });
199 ServiceOffer[] servicesOffers =
200 registryService.findByCriteria(new String[] { "ProjectDataService" },
201 new Property[] { property });
202 if (servicesOffers.length == 0) {
203 throw new OpenDreamsException("Não foi encontrado um serviço com "
204 + "identificador: " + componentId);
205 }
206 if (servicesOffers.length > 1) {
207 throw new OpenDreamsException("Foi encontrado mais de um serviço com "
208 + "identificador: " + componentId);
209 }
210 ServiceOffer serviceOffer = servicesOffers[0];
211 IComponent component = serviceOffer.member;
212 org.omg.CORBA.Object dataserviceObject =
213 component.getFacet(IHierarchicalDataServiceHelper.id());
214 dataService = IHierarchicalDataServiceHelper.narrow(dataserviceObject);
215 }
216 return dataService;
217 }
218
219 /**
220 * Obtém um proxy para um projeto do usuário. O nome do projeto deve estar
221 * definido na propriedade <code>opendreams.project.name</code>. do arquivo
222 * de configuração.
223 *
224 * @return um projeto.
225 * @throws OpenDreamsException se ocorrer um erro no acesso ao serviço de
226 * projetos
227 */
228 public Project getProject() throws OpenDreamsException {
229 String projectName = properties.getProjectName();
230 if (projectName == null || projectName.isEmpty()) {
231 throw new OpenDreamsException(
232 "Propriedade opendreams.project.name não definida");
233 }
234 return getProject(projectName);
235 }
236
237 /**
238 * Obtém um proxy para um projeto do usuário.
239 *
240 * @param projectName nome do projeto
241 *
242 * @return um projeto.
243 * @throws OpenDreamsException se ocorrer um erro no acesso ao serviço de
244 * projetos
245 */
246 public Project getProject(String projectName) throws OpenDreamsException {
247 IHierarchicalDataService dataService = this.getIDataService();
248 DataDescription[] rootDescList;
249 try {
250 rootDescList = dataService.getRoots();
251 if (rootDescList.length < 1) {
252 throw new OpenDreamsException("O usuário não possui projetos");
253 }
254 for (int i = 0; i < rootDescList.length; i++) {
255 DataDescription rootDesc = rootDescList[i];
256 if (!(rootDesc instanceof ProjectItemDescription)) {
257 throw new OpenDreamsException("Descritor inválido:"
258 + rootDesc.toString());
259 }
260 if (rootDesc.fName.equals(projectName)) {
261 return new Project(rootDesc, properties.getUser(), dataService);
262 }
263 }
264 }
265 catch (ServiceFailure e) {
266 throw new OpenDreamsException("Falha no acesso ao serviço de projetos", e);
267 }
268 catch (DataAccessDenied e) {
269 throw new OpenDreamsException("Falha no acesso ao serviço de projetos", e);
270 }
271 return null;
272 }
273
274 /**
275 * Fecha a conexão com o openbus.
276 *
277 * @throws OpenDreamsException falha no acesso ao openbus
278 */
279 public void close() throws OpenDreamsException {
280 Openbus.getInstance().disconnect();
281 }
282
283 /**
284 * Faz o registro no ORB das fábricas necessárias para construção
285 * (marshalling) dos value types.
286 */
287 private void registerFactories() {
288 Openbus bus = Openbus.getInstance();
289 ORB orb = (ORB) bus.getORB();
290 // Fábricas do OpenDreams
291 orb.register_value_factory(OpenDreamsJobTemplateHelper.id(),
292 new OpenDreamsJobTemplateFactory());
293 orb.register_value_factory(JobParameterHelper.id(),
294 new JobParameterFactory());
295 orb.register_value_factory(JobInfoHelper.id(), new JobInfoFactory());
296 // Fábricas do Serviço de Projetos
297 orb.register_value_factory(ProjectItemDescriptionHelper.id(),
298 new ProjectItemDescriptionFactory());
299 orb.register_value_factory(UnstructuredDataHelper.id(),
300 new UnstructuredDataFactory());
301 }
302
303 /**
304 * Obtém o identificador do componente de acordo com o nome e a versão desse
305 * componente. Esse identificador é usado para encontrar o componente no
306 * OpenBus.
307 *
308 * @return o identificador do componente.
309 */
310 private String getComponentId(String componentName, String componentVersion) {
311 final String[] tmp = componentVersion.split("[\\.]");
312 StringBuffer componentId = new StringBuffer(componentName);
313 componentId.append(':');
314 for (String s : tmp) {
315 componentId.append(s.trim());
316 }
317 return componentId.toString();
318 }
319
320 /**
321 * Obtém as propriedades usadas por esse proxy.
322 *
323 * @return as propriedades do acesso ao OpenDreams
324 */
325 public OpenDreamsProperties getProperties() {
326 return properties;
327 }
328 }