Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate Facilities #18

Open
wants to merge 44 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
554190a
Separate Facilities
slominskir Jan 27, 2025
94257c7
Separate Facilities
slominskir Jan 27, 2025
1d4e62d
Separate Facilities
slominskir Jan 27, 2025
cdf831d
Separate Facilities
slominskir Jan 27, 2025
ac53394
Separate Facilities
slominskir Jan 27, 2025
d795a59
Separate Facilities
slominskir Jan 27, 2025
ce358db
Separate Facilities
slominskir Jan 28, 2025
060aef6
Separate Facilities
slominskir Jan 28, 2025
8f106ea
Separate Facilities
slominskir Jan 28, 2025
cb3888f
Separate Facilities
slominskir Jan 28, 2025
5c8191c
Separate Facilities
slominskir Jan 28, 2025
f4fb785
Separate Facilities
slominskir Jan 28, 2025
902028b
Separate Facilities
slominskir Jan 28, 2025
e5bb015
Separate Facilities
slominskir Jan 28, 2025
c84ab34
Separate Facilities
slominskir Jan 28, 2025
623ca62
Separate Facilities
slominskir Jan 28, 2025
49b1792
Separate Facilities
slominskir Jan 28, 2025
1965326
Separate Facilities
slominskir Jan 28, 2025
bc6a485
Separate Facilities
slominskir Jan 28, 2025
e2f9572
Separate Facilities
slominskir Jan 28, 2025
50ebd49
Separate Facilities
slominskir Jan 29, 2025
05a05d5
Separate Facilities
slominskir Jan 29, 2025
a5df2b5
Separate Facilities
slominskir Jan 29, 2025
c4607e1
Separate Facilities
slominskir Jan 29, 2025
4b4e859
Separate Facilities
slominskir Jan 29, 2025
0c87261
Separate Facilities
slominskir Jan 29, 2025
6d2d20e
Separate Facilities
slominskir Jan 29, 2025
ef89fe1
Separate Facilities
slominskir Jan 29, 2025
0bb9b36
Separate Facilities
slominskir Jan 29, 2025
dd0d5e7
Separate Facilities
slominskir Jan 29, 2025
07aceba
Separate Facilities
slominskir Jan 30, 2025
8a1a5a3
Separate Facilities
slominskir Jan 30, 2025
f4e7da8
Separate Facilities
slominskir Jan 30, 2025
dad4c8d
Separate Facilities
slominskir Jan 30, 2025
05d9122
Separate Facilities
slominskir Jan 30, 2025
2177c35
Separate Facilities
slominskir Jan 30, 2025
b3ec898
Separate Facilities
slominskir Jan 30, 2025
fd6e9cd
Separate Facilities
slominskir Jan 30, 2025
ef4ee46
Separate Facilities
slominskir Jan 30, 2025
067c335
Separate Facilities
slominskir Jan 30, 2025
17e9752
Separate Facilities
slominskir Jan 30, 2025
99520c0
Separate Facilities
slominskir Jan 30, 2025
719e70c
Separate Facilities
slominskir Jan 30, 2025
3a8d88d
Separate Facilities
slominskir Jan 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ A [Java EE 8](https://en.wikipedia.org/wiki/Jakarta_EE) web application for both
---

## Overview
The Authorization application allows the Director of Operations (or a delegate) to clearly communicate and document authorization for various facilities at JLab to either generate beam or engage in RF operations. For beam generation the maximum current and beam mode ("permissions") that are authorized are provided for a given beam destination. This information is stored in a database and presented via the web for easy access. There are three beam generating facilities, each with their own set of beam destinations and beam modes: CEBAF, LERF, UITF. There are seven facilities which generate RF: CEBAF Injector, CEBAF North Linac, CEBAF South Linac, LERF, CMTF, and VTA. In addition to director authorization, the app also tracks Credited Controls and their verification. Each beam destination is assigned a set of controls and each control is assigned to a particular responsible group. A beam desintation is ready for beam only if all the controls assigned are verified by their responsible group. Both group verifications and director permissions have expirations. Emails and Jefferson Lab logbook entires are created to aid communication of new director permissions, responsible group verifications (upgrades and downgrades), and verification and permissions expirations.
The authorization application allows the Director of Operations (or a delegate) to clearly communicate and document authorization for various facilities at JLab to either generate beam or engage in RF operations. For beam generation the maximum current and beam mode ("permissions") that are authorized are provided for a given beam destination. This information is stored in a database and presented via the web for easy access. There are three beam generating facilities, each with their own set of beam destinations and beam modes: CEBAF, LERF, UITF. There are seven facilities which generate RF: CEBAF Injector, CEBAF North Linac, CEBAF South Linac, LERF, CMTF, and VTA. In addition to director authorization, the app also tracks Credited Controls and their verification. Each beam destination is assigned a set of controls and each control is assigned to a particular responsible group. A beam desintation is ready for beam only if all the controls assigned are verified by their responsible group. Both group verifications and director permissions have expirations. Emails and Jefferson Lab logbook entires are created to aid communication of new director permissions, responsible group verifications (upgrades and downgrades), and verification and permissions expirations.

### Roles
- **Operations Director** - Responsible for authorizing beam
Expand Down
319 changes: 235 additions & 84 deletions container/oracle/initdb.d/02_ddl.sql

Large diffs are not rendered by default.

139 changes: 88 additions & 51 deletions container/oracle/initdb.d/03_default_data.sql

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
package org.jlab.jam.business.session;

import java.math.BigInteger;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.security.DeclareRoles;
import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import org.jlab.jam.persistence.entity.BeamAuthorization;
import org.jlab.jam.persistence.entity.BeamDestination;
import org.jlab.jam.persistence.entity.BeamDestinationAuthorization;
import org.jlab.jam.persistence.entity.Facility;
import org.jlab.smoothness.business.exception.UserFriendlyException;

/**
* @author ryans
*/
@Stateless
@DeclareRoles({"jam-admin"})
public class BeamAuthorizationFacade extends AbstractFacade<BeamAuthorization> {

private static final Logger LOGGER = Logger.getLogger(BeamAuthorizationFacade.class.getName());

@PersistenceContext(unitName = "jamPU")
private EntityManager em;

@EJB BeamDestinationFacade destinationFacade;

@Override
protected EntityManager getEntityManager() {
return em;
}

public BeamAuthorizationFacade() {
super(BeamAuthorization.class);
}

@SuppressWarnings("unchecked")
@PermitAll
public HashMap<BigInteger, String> getUnitsMap() {
HashMap<BigInteger, String> units = new HashMap<>();

Query q =
em.createNativeQuery(
"select a.BEAM_DESTINATION_ID, a.CURRENT_LIMIT_UNITS from beam_destination a where a.ACTIVE_YN = 'Y'");

List<Object[]> results = q.getResultList();

for (Object[] result : results) {
Object[] row = result;
Number id = (Number) row[0];
String unit = (String) row[1];
// LOGGER.log(Level.WARNING, "ID: {0}, Unit: {1}", new Object[]{id, unit});
units.put(BigInteger.valueOf(id.longValue()), unit);
}

return units;
}

@SuppressWarnings("unchecked")
@PermitAll
public BeamAuthorization findCurrent() {
Query q =
em.createNativeQuery(
"select * from (select * from beam_authorization order by modified_date desc) where rownum <= 1",
BeamAuthorization.class);

List<BeamAuthorization> beamAuthorizationList = q.getResultList();

BeamAuthorization beamAuthorization = null;

if (beamAuthorizationList != null && !beamAuthorizationList.isEmpty()) {
beamAuthorization = beamAuthorizationList.get(0);
}

return beamAuthorization;
}

@SuppressWarnings("unchecked")
@PermitAll
public List<BeamAuthorization> findHistory(int offset, int maxPerPage) {
Query q =
em.createNativeQuery(
"select * from beam_authorization order by authorization_date desc",
BeamAuthorization.class);

return q.setFirstResult(offset).setMaxResults(maxPerPage).getResultList();
}

@PermitAll
public Long countHistory() {
TypedQuery<Long> q = em.createQuery("select count(a) from BeamAuthorization a", Long.class);

return q.getSingleResult();
}

@PermitAll
public Map<BigInteger, BeamDestinationAuthorization> createDestinationAuthorizationMap(
BeamAuthorization beamAuthorization) {
Map<BigInteger, BeamDestinationAuthorization> destinationAuthorizationMap = new HashMap<>();

if (beamAuthorization != null && beamAuthorization.getDestinationAuthorizationList() != null) {
for (BeamDestinationAuthorization beamDestinationAuthorization :
beamAuthorization.getDestinationAuthorizationList()) {
destinationAuthorizationMap.put(
beamDestinationAuthorization.getDestinationAuthorizationPK().getBeamDestinationId(),
beamDestinationAuthorization);
}
}

return destinationAuthorizationMap;
}

@RolesAllowed("jam-admin")
public void saveAuthorization(
Facility facility,
String comments,
List<BeamDestinationAuthorization> beamDestinationAuthorizationList)
throws UserFriendlyException {
String username = checkAuthenticated();

BeamAuthorization beamAuthorization = new BeamAuthorization();
beamAuthorization.setFacility(facility);
beamAuthorization.setComments(comments);
beamAuthorization.setAuthorizationDate(new Date());
beamAuthorization.setAuthorizedBy(username);
beamAuthorization.setModifiedDate(beamAuthorization.getAuthorizationDate());
beamAuthorization.setModifiedBy(username);

create(beamAuthorization);

for (BeamDestinationAuthorization da : beamDestinationAuthorizationList) {

BeamDestination destination =
destinationFacade.find(da.getDestinationAuthorizationPK().getBeamDestinationId());
if (!"None".equals(da.getBeamMode())) { // CW or Tune

// Check if credited control agrees
if (!(destination.getVerification().getVerificationStatusId() <= 50)) {
throw new UserFriendlyException(
"Beam Destination \""
+ destination.getName()
+ "\" cannot have beam when credited controls are not verified");
}

// If provisional then there better be a comment
if (destination.getVerification().getVerificationStatusId() == 50
&& (da.getComments() == null || da.getComments().trim().isEmpty())) {
throw new UserFriendlyException(
"Beam Destination \""
+ destination.getName()
+ "\" must have a comment to explain why beam is permitted with provisional credited control status");
}

// Must provide an expiration date since CW or Tune
if (da.getExpirationDate() == null) {
throw new UserFriendlyException(
"Beam Destination \""
+ destination.getName()
+ "\" must have an expiration date since beam is allowed");
}

// Expiration must be in the future
Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR_OF_DAY, 1);
if (da.getExpirationDate().before(cal.getTime())) {
throw new UserFriendlyException(
"Beam Destination \""
+ destination.getName()
+ "\" must have a future expiration date and minimum expiration is 1 hour from now");
}
}

da.setAuthorization(beamAuthorization);
da.getDestinationAuthorizationPK()
.setAuthorizationId(beamAuthorization.getBeamAuthorizationId());
em.persist(da);
}

LOGGER.log(Level.FINE, "Director's Authorization saved successfully");
}
}
Loading